diff --git a/CHANGELOG.md b/CHANGELOG.md index 36915e781..64adc34bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,36 @@ ### Changelog +#### Version 0.42.1 +* Fix accepting/rejecting calls on Android 9 +* Mi Band 3/4, Amazfit Bip/Cor/GTS/GTR: Option to sync calendar events as reminder + +#### Version 0.42.0 +* Initial iTag support +* Fix indefinitely lasting Bluetooth scans when location permission has not been granted +* Try to stop incoming VoIP call notification when the call is answered +* Vectorize some icons and add a new Mi Scale 2 icon +* Mi Band 4: Make high MTU optional, fixes problems on some phones +* ZeTime: Fix probably broken support (duplicate id used by Fossil) + +#### Version 0.41.1 +* Huami: allow to have alarms without snooze feature +* Mi Band 2: Properly stop a call notification when text notifications are disabled +* VoIP calls: ignore notifications with only one action, assuming it is an outgoing call +* Try to fix notifications from Business Calendar + +#### Version 0.41.0 +* JYou Y5: Initial support +* Mi Band 2/Amazfit Bip: Redesign button actions for easy music control setup and support long presses on Bip +* Amazfit Bip: Remove RES file limit (for BipOS) +* Huami: Automatically toggle alarm switch when toggling on the Band/Watch while in Alarm settings in Gadgetbridge +* Recognize Pixart-Messenger as Chat App + +#### Version 0.40.1 +* Mi Band/Amazfit: Recognize changes when toggling alarm on device (immediately when connected, else when connecting) +* Mi Band/Amazfit: Fix some bugs with stuck connection when re-connecting +* Mi Band 4: Support higher MTU for multiple times faster firmware transfer (probably also Amazfit GTR/GTS) +* Amazfit Cor: Fix setting language to Chinese manually + #### Version 0.40.0 * Fossil Q Hybrid: Initial support * Bangle.js: Initial support @@ -8,7 +39,7 @@ #### Version 0.39.1 * Try to actively re-connect when a connection gets interrupted (interval grows up to 64 seconds) -* Mi Band2/Amazfip Bip: Make button action settings per-device and enable for Amazfit Bip +* Mi Band2/Amazfit Bip: Make button action settings per-device and enable for Amazfit Bip #### Version 0.39.0 * Amazfit GTS: Initial and incomplete support, mostly untested @@ -19,14 +50,14 @@ * Amazfit GTR: Initial and incomplete support, mostly untested * Amazfit Bip: add Portuguese to the list of selectable languages * Mi Band 4: Enable emoji font setting -* Makibes HR3: Support the english version -* Makibes HR3: Enable bluetooth pairing for working reconnection +* Makibes HR3: Support the English version +* Makibes HR3: Enable Bluetooth pairing for working re-connection * Work around crash when trying to display changelog * Sleep detection settings: Rolling 24 hours (existing style) or Noon to noon -* Add alternative color to heartrate in chart settings +* Add alternative color to heart rate in chart settings #### Version 0.37.1 -* Amazfit Bip Lite: Support flashing firmware and watchfaces +* Amazfit Bip Lite: Support flashing firmware and watch faces #### Version 0.37.0 * Initial Makibes HR3 support @@ -40,7 +71,7 @@ * Show toast in case no app is installed which can handle GPX files * Mi Band 4/Amazfit Bip Lite: Trim white spaces and new lines from auth key * Mi Band 4/Amazfit Bip Lite: Display a toast and do not try to pair if there was no auth key supplied -* Skip service scan if supported device could be recognized without uuids during discovery +* Skip service scan if supported device could be recognized without UUIDs during discovery #### Version 0.36.2 * Amazfit Bip: Untested support for Lite variant @@ -50,7 +81,7 @@ #### Version 0.36.1 * Mi Band 2/3/4, Amazfit Bip/Cor: Add setting to expose the HR sensor to 3rd party apps * Mi Band 4: Really fix weather location not being updated on the Band -* Mi Band 4: Fix call notifcation not stopping when call gets answered or rejected on the phone +* Mi Band 4: Fix call notification not stopping when call gets answered or rejected on the phone * Amazfit Bip/Cor: Support for custom emoji font * ZeTime: Enable emoji support * ZeTime: Make watch language the same as the phone language by default @@ -64,7 +95,7 @@ * Initial Mijia LYWSD02 support (Smart Clock with Humidity and Temperature Sensor), just for setting the time * Mi Band 3/4: Allow enabling the NFC menu where supported (useless for now) * Mi Band 3/4, Amazfit Cor/Bip: Set language immediately when changing it (not only on connect) -* Mi Band 3/4, Amazfir Cor/Bip: Add icons for "swimming" and "exercise" +* Mi Band 3/4, Amazfit Cor/Bip: Add icons for "swimming" and "exercise" * Mi Band 4: Support flashing the V2 font * Mi Band 4: Fix weather location not being updated on the Band * Mi Band 4: remove unsupported DND setting from settings menu @@ -78,11 +109,11 @@ #### Version 0.35.2 * Mi Band 1/2: Crash when updating firmware while phone is set to Spanish * Mi Band 4: Enable music info support (displays now on the band) -* Mi Band 4: Support setting date format (for built-in watchfaces) +* Mi Band 4: Support setting date format (for built-in watch-faces) * Amazfit Cor 2: Try to fix empty menu on device #### Version 0.35.1 -* Mi Band 4: Support flashing watchfaces, res and firmware (.ft untested) +* Mi Band 4: Support flashing watch-faces, res and firmware (.ft untested) #### Version 0.35.0 * Mi Band 4: Initial support (WARNING: INITIAL SETUP NEEDS MI FIT WITH ACCOUNT AND ROOT, NOT A RECOMMENDED DEVICE FOR GADGETBRIDGE) @@ -90,7 +121,7 @@ #### Version 0.34.1 * Mi Band 1: Fix crash when entering per-device settings * Mi Band 3: Allow setting date format in per-device settings -* ZeTime: Fix timestmaps +* ZeTime: Fix time stamps * Fix a crash when flashing an non-whitelisted firmware while using Gadgetbridge in Spanish #### Version 0.34.0 @@ -110,14 +141,14 @@ * Mi Band 3: Add Indonesian, Thai, Arabic, Vietnamese, Portuguese, Dutch, Turkish and Ukrainian to language settings * Mi Band 3: Support flashing latest Japanese-Korean font * Amazfit Cor 2: Initial experimental support (untested) -* Pebble: Add pebblekit extension for reopening last app -* Casio: Bugfixes and improvements +* Pebble: Add PebbleKit extension for reopening last app +* Casio: Bug fixes and improvements * Lookup contacts also in work profile * Fix searching in application name when blacklisting * Remove misleading title from database management activity when no legacy database is available #### Version 0.32.4 -* Make voip call support optional (disabled by default) +* Make VoIP call support optional (disabled by default) * Amazfit Bip: GPX export corrections * ZeTime: Fix setting alarms * ZeTime: Fix wrong activity timestamps @@ -143,9 +174,9 @@ * Initial support for Casio GB-6900B * Increase number of alarms and store them per-device * Support factory reset in debug activity (Mi Band 1/2/3, Bip, Cor) -* Filter out unicode control sequences (fixes problems with Telegram and probably others) +* Filter out Unicode control sequences (fixes problems with Telegram and probably others) * Fix endless loop resulting in OOM when RTL support is enabled -* Recoginize p≡p as an email app +* Recognize p≡p as an email app * No longer display Android paired devices in that were not a paired with Gadgetbridge * Amazfit Bip: Allow flashing latest GPS firmware * Pebble: Native support for M7S watch face @@ -168,8 +199,8 @@ #### Version 0.31.0 * Pebble: Send all wearable notification actions (not only reply) * Pebble: Always allow reply action even if untested features are turned off -* Pebble: Temporarily disable broken autoremove notification feature -* Amazfit Bip: Allow flashing latest gps firmware (Mili_dth.gps) +* Pebble: Temporarily disable broken auto remove notification feature +* Amazfit Bip: Allow flashing latest GPS firmware (Mili_dth.gps) * Mi Band 3/Amazfit Bip/Amazfit Cor: Send Fahrenheit if units are set to imperial * Roidmi 3: Fix and enable support * Mi Band 3/Amazfit Bip: fix find phone crash @@ -253,7 +284,7 @@ * Initial support for Mi Band 3 (largely untested, needs to be connected to Mi Fit once) * Option for automatic activity sync after screen unlock * Allow hiding activity transfer notification on Android Oreo and above -* Allow blacklisting of pebblekit notifications for individual apps +* Allow blacklisting of PebbleKit notifications for individual apps * Allow blacklisting all application at once * Forward Skype notifications to wearable even if "local only" flag is set * Show Gadgetbridge logo behind cards in main activity @@ -554,7 +585,7 @@ #### Version 0.17.5 * Automatically start the service on boot (can be turned off) -* Pebble: PebbleKit compatibility improvements (Datalogging) +* Pebble: PebbleKit compatibility improvements (Data logging) * Pebble: Display music shuffle and repeat states for some players * Pebble 2/LE: Speed up data transfer @@ -562,7 +593,7 @@ * Better integration with android music players * Privacy options for calls (hide caller name/number) * Send a notification to the connected if the Android Alarm Clock rings (com.android.deskclock) -* Fixes for cyrillic transliteration +* Fixes for Cyrillic transliteration * Pebble: Implement notification privacy modes * Pebble: Support weather for Obisdian watchface * Pebble: add a dev option to always and immediately ACK PebbleKit messages to the watch @@ -633,7 +664,7 @@ * Mi Band 2: Initial support for firmware update (tested so far: 1.0.0.39) #### Version 0.14.4 -* Pebble 2/LE: Fix multiple bugs in reconnection code, honor reconnect tries from settings +* Pebble 2/LE: Fix multiple bugs in re-connection code, honor reconnect tries from settings * Mi Band 2: Experimental support for activity recognition * Mi Band 2: Fix time setting code @@ -678,7 +709,7 @@ * Mi Band 2: Initial support for heart rate readings (Debug activity only) * Mi Band 2: Support disabled alarms * Attempt to fix spurious device discovery problems -* Correctly recognize Toffeed, Slimsocial and MaterialFBook as facebook notification sources +* Correctly recognize Toffeed, Slimsocial and MaterialFBook as Facebook notification sources #### Version 0.13.6 * Mi Band 2: Support for multiple alarms (3 at the moment) @@ -694,10 +725,10 @@ * Mi Band: Support for testing vibration patterns directly from the preferences * Mi Band: Clean up vibration preferences * Possibly fix logging to file on certain devices (#406) -* Mi Band 2: Possibly fix weird connection interdependency between Mi 1 and 2 (#323) -* Mi Band 1S: Whitelist firmware 4.16.4.22 +* Mi Band 2: Possibly fix weird connection interdependence between Mi 1 and 2 (#323) +* Mi Band 1S: White list firmware 4.16.4.22 * Mi Band: try application level pairing again, in order to support data sharing with Mi Fit (#250) -* Pebble: new icons and colours for certain apps +* Pebble: new icons and colors for certain apps * Debug-screen: added button to test "new functionality", currently live sensor data for Mi Band 1 #### Version 0.13.3 @@ -747,7 +778,7 @@ * Fix a rare crash when, due to Bluetooth problems, when a device has no name * Fix activity fetching getting stuck when double tapping (#333) * Mi Band: in the Device Discovery activity, do not display devices that are already paired -* Mi Band: only allow automatic reconnection on disconnect when the device was previously fully connected +* Mi Band: only allow automatic re-connection on disconnect when the device was previously fully connected * Mi Band: fix a rare crash when reading data fails due to Bluetooth problems * Mi Band: log full activity sample to help deciphering activity kinds (#341) * Mi Band 2: improved discovery mechanism to not rely on MAC addresses (#323) @@ -819,7 +850,7 @@ #### Version 0.9.4 * Pebble: support pebble health datalog messages of firmware 3.11 (this adds support for deep sleep!) * Pebble: try to reconnect on new notifications and phone calls when connection was lost unexpectedly -* Pebble: delay between reconnection attempts (from 1 up to 64 seconds) +* Pebble: delay between re-connection attempts (from 1 up to 64 seconds) * Fix crash in charts activities when changing the date, quickly (#277) * Mi Band: preference to enable heart rate measurement during sleep (#232, thanks computerlyrik!) * Mi Band: display measured heart rate in charts (#232) @@ -875,7 +906,7 @@ * Fix layout of the alarms activity #### Version 0.7.4 -* Refactored the settings activity: User details are now generic instead of miband specific. Old settings are preserved. +* Refactored the settings activity: User details are now generic instead of Mi Band specific. Old settings are preserved. * Pebble: Fix regression with broken active reconnect since 0.7.0 * Pebble: Support activation and deactivation of Pebble Health. Activation uses the User details as seen above. Insights are NOT activated. Please be aware that deactivation does NOT delete the data stored on the watch (but it seems to stop the tracking), and we do not know how to switch to metric length units. @@ -893,7 +924,7 @@ * Sort blacklist by package names #### Version 0.7.1 -* Pebble: allow reinstallation of apps in pbw-cache from App Manager (long press menu) +* Pebble: allow re-installation of apps in pbw-cache from App Manager (long press menu) * Pebble: Fix regression which freezes Gadgetbridge when disconnecting via long-press menu #### Version 0.7.0 @@ -902,7 +933,7 @@ * Pebble: Support replying to SMS form the watch (canned replies) * Pebble: Allow installing apps compiled with SDK 2.x also on the basalt platform (Time, Time Steel) * Pebble: Fix decoding strings in appmessages from the pebble (fixes sending SMS from "Dialer for Pebble") -* Pebble: Support incoming reconnections when device returns from "Airplane Mode" or "Stand-By Mode" +* Pebble: Support incoming re-connections when device returns from "Airplane Mode" or "Stand-By Mode" * Pebble: Fix crash when turning off Bluetooth when connected on Android 6.0 * Mi Band: reserve some alarm slots for alerting when upcoming events begin. NB: the band will vibrate at the start time of the event, android reminders are ignored * Mi Band: Display unique devices Names, not just "MI" @@ -961,7 +992,7 @@ * Try to prevent service being killed by disallowing backups #### Version 0.6.2 -* Mi Band: support firmware version 1.0.10.14 (and onwards?) vibration +* Mi Band: support firmware version 1.0.10.14 (and onward?) vibration * Mi Band: get device name from official BT SIG endpoint * Mi Band: initial support for displaying live activity data, screen stays on @@ -969,12 +1000,12 @@ * Pebble: Allow muting (blacklisting) Apps from within generic notifications on the watch * Pebble: Detect all known Pebble Versions including new "chalk" platform (Pebble Time Round) * Option to ignore phone calls (useful for Pebble Dialer) -* Mi Band: Added progressbar for activity data transfer and fixes for firmware transfer progressbar +* Mi Band: Added progress bar for activity data transfer and fixes for firmware transfer progress bar * Bugfix for app blacklist (some checkboxes where wrongly drawn as checked) #### Version 0.6.0 * Pebble: WIP implementation of PebbleKit Intents to make some 3rd party Android apps work with the Pebble (eg. Ventoo) -* Pebble: Option to set reconnection attempts in settings (one attempt usually takes about 5 seconds) +* Pebble: Option to set re-connection attempts in settings (one attempt usually takes about 5 seconds) * Support controlling all audio players that react to media buttons (can be chosen in settings) * Treat SMS as generic notification if set to "never" (can be blacklisted there also if desired) * Treat Conversations messages as chat messages, even if arrived via Pebble Intents (nice icon for Pebble FW 3.x) @@ -1024,7 +1055,7 @@ * Fixed slight steps graph distortion through black text labels * Fixed control center activity and notification showing different device connection state * Small firmware installation improvements -* Various refactorings and code cleanups +* Various refactoring and code cleanups #### Version 0.4.5 * Enhancement to activity graphs: new graph showing the number of steps done today and in the last week diff --git a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java index a8ab19315..2538468f4 100644 --- a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java +++ b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java @@ -15,8 +15,6 @@ */ package nodomain.freeyourgadget.gadgetbridge.daogen; -import java.util.Date; - import de.greenrobot.daogenerator.DaoGenerator; import de.greenrobot.daogenerator.Entity; import de.greenrobot.daogenerator.Index; @@ -45,7 +43,7 @@ public class GBDaoGenerator { public static void main(String[] args) throws Exception { - Schema schema = new Schema(21, MAIN_PACKAGE + ".entities"); + Schema schema = new Schema(24, MAIN_PACKAGE + ".entities"); Entity userAttributes = addUserAttributes(schema); Entity user = addUserInfo(schema, userAttributes); @@ -72,6 +70,7 @@ public class GBDaoGenerator { addXWatchActivitySample(schema, user, device); addZeTimeActivitySample(schema, user, device); addID115ActivitySample(schema, user, device); + addJYouActivitySample(schema, user, device); addWatchXPlusHealthActivitySample(schema, user, device); addWatchXPlusHealthActivityKindOverlay(schema, user, device); @@ -332,6 +331,19 @@ public class GBDaoGenerator { return activitySample; } + private static Entity addJYouActivitySample(Schema schema, Entity user, Entity device) { + Entity activitySample = addEntity(schema, "JYouActivitySample"); + activitySample.implementsSerializable(); + addCommonActivitySampleProperties("AbstractActivitySample", activitySample, user, device); + activitySample.addIntProperty(SAMPLE_STEPS).notNull().codeBeforeGetterAndSetter(OVERRIDE); + activitySample.addIntProperty(SAMPLE_RAW_KIND).notNull().codeBeforeGetterAndSetter(OVERRIDE); + activitySample.addIntProperty("caloriesBurnt"); + activitySample.addIntProperty("distanceMeters"); + activitySample.addIntProperty("activeTimeMinutes"); + addHeartRateProperties(activitySample); + return activitySample; + } + private static Entity addWatchXPlusHealthActivitySample(Schema schema, Entity user, Entity device) { Entity activitySample = addEntity(schema, "WatchXPlusActivitySample"); activitySample.implementsSerializable(); @@ -404,12 +416,14 @@ public class GBDaoGenerator { alarm.addIndex(indexUnique); alarm.addBooleanProperty("enabled").notNull(); alarm.addBooleanProperty("smartWakeup").notNull(); + alarm.addBooleanProperty("snooze").notNull(); alarm.addIntProperty("repetition").notNull().codeBeforeGetter( "public boolean isRepetitive() { return getRepetition() != ALARM_ONCE; } " + "public boolean getRepetition(int dow) { return (this.repetition & dow) > 0; }" ); alarm.addIntProperty("hour").notNull(); alarm.addIntProperty("minute").notNull(); + alarm.addBooleanProperty("unused").notNull(); alarm.addToOne(user, userId); alarm.addToOne(device, deviceId); } diff --git a/README.md b/README.md index 08489e51d..ee309beaa 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,9 @@ vendor's servers. * Casio GB-6900B * Fossil Q Hybrid * HPlus Devices (e.g. ZeBand) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/HPlus) +* iTag * ID115 +* JYou Y5 * Lenovo Watch 9 * Lenovo Watch X (Plus) [Wiki](https://codeberg.org/mamutcho/Gadgetbridge/wiki) * Liveview @@ -47,13 +49,13 @@ vendor's servers. * Mi Band 2 [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-2) * Mi Band 3 [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-3) * Mi Band 4 (NOT RECOMMENDED, NEEDS MI FIT WITH ACCOUNT AND ROOT ONCE) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-4) -* Mi Scale 2 (currently only displays a toast after stepping on the scale) +* Mi Scale 2 (Currently only displays a toast after stepping on the scale) * NO.1 F1 * Pebble, Pebble Steel, Pebble Time, Pebble Time Steel, Pebble Time Round [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Pebble) * Pebble 2 [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Pebble) * Teclast H10, H30 * XWatch (Affordable Chinese Casio-like smartwatches) -* Vibratissimo (experimental) +* Vibratissimo (Experimental) * ZeTime [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/MyKronoz-ZeTime) @@ -83,6 +85,8 @@ Please see [FEATURES.md](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/ma * Lukas Schwichtenberg (Makibes HR3) * Daniel Dakhno (Fossil Q Hybrid) * Gordon Williams (Bangle.js) +* Pavel Elagin (JYou Y5) +* Taavi Eomäe (iTag) ## Contribute @@ -92,6 +96,12 @@ just leave a comment that you're working on one to avoid duplicated work. Translations can be contributed via https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ +## Community + +If you would like to get in touch with other Gadgetbridge users and developers outside of Codeberg, you can do so via: +* Matrix: #gadgetbridge:matrix.org - The most active channel +* IRC: #gadgetbridge on Freenode + ## Do you have further questions or feedback? Feel free to open an issue on our issue tracker, but please: @@ -109,4 +119,3 @@ Feel free to open an issue on our issue tracker, but please: 4. File an issue at https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/new and possibly provide the logfile Alternatively you may use the standard logcat functionality to access the log. - diff --git a/app/build.gradle b/app/build.gradle index 893e36c2a..0054e1289 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,11 +22,11 @@ android { defaultConfig { applicationId "nodomain.freeyourgadget.gadgetbridge" minSdkVersion 19 - targetSdkVersion 27 + targetSdkVersion 28 // Note: always bump BOTH versionCode and versionName! - versionName "0.40.0" - versionCode 163 + versionName "0.43.0" + versionCode 169 vectorDrawables.useSupportLibrary = true } buildTypes { @@ -73,7 +73,7 @@ dependencies { implementation "androidx.recyclerview:recyclerview:1.1.0" implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.gridlayout:gridlayout:1.0.0" - implementation "com.google.android.material:material:1.0.0" + implementation "com.google.android.material:material:1.1.0" implementation "androidx.palette:palette:1.0.0" implementation("com.github.tony19:logback-android-classic:1.1.1-6") { exclude group: "com.google.android", module: "android" diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index dc8ca6043..4ed7b1acb 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -9,9 +9,26 @@ # Add any project specific keep options here: -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} +# Pebble BG-JS +-keepclassmembers class * { + @android.webkit.JavascriptInterface ; +} +-keepclassmembers class nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.JSInterface { + public *; +} +-keepattributes JavascriptInterface + +# https://github.com/tony19/logback-android/issues/29 +-dontwarn javax.mail.**, javax.naming.Context, javax.naming.InitialContext + +# To avoid any stacktrace ambiguity +-keepattributes SourceFile,LineNumberTable + +# GreenDAO 2 - http://greenrobot.org/greendao/documentation/technical-faq/ +-keepclassmembers class * extends de.greenrobot.dao.AbstractDao { + public static java.lang.String TABLENAME; +} + +-keep class **$Properties + +-keep class **$Properties { *; } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d283f50fd..d26098282 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ - - @@ -44,16 +43,19 @@ android:allowBackup="false" android:fullBackupContent="false" android:icon="@mipmap/ic_launcher" - android:roundIcon="@mipmap/ic_launcher_round" android:label="@string/app_name" + android:roundIcon="@mipmap/ic_launcher_round" android:theme="@style/GadgetbridgeTheme"> + + + @@ -82,9 +84,9 @@ android:label="@string/activity_summaries" android:parentActivityName=".activities.ControlCenterv2" /> - + @@ -310,7 +312,6 @@ - @@ -335,18 +336,19 @@ - + - + - @@ -369,16 +371,13 @@ - - - + android:exported="false"> + --> + android:label="@string/title_activity_watch9_pairing" /> + android:label="@string/title_activity_watch9_calibration" /> @@ -439,8 +438,8 @@ + android:parentActivityName=".activities.AppBlacklistActivity" + android:windowSoftInputMode="stateHidden|adjustPan" /> @@ -449,7 +448,6 @@ android:name=".contentprovider.PebbleContentProvider" android:authorities="com.getpebble.android.provider" android:exported="true" /> - - @@ -471,41 +470,41 @@ android:name="android.appwidget.provider" android:resource="@xml/sleep_alarm_widget_info" /> - - + - - + android:theme="@style/Theme.AppCompat.Light.Dialog" /> + - - - + + + + + @@ -515,6 +514,9 @@ + - + \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 460f85eb7..4d3c7ec49 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Martin, Matthieu Baerts, Normano64, Pavel Elagin, Taavi Eomäe This file is part of Gadgetbridge. @@ -90,7 +90,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.MIBAND4; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.ZETIME; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.fromKey; import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_CHANNEL_ID; - +import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_CHANNEL_HIGH_PRIORITY_ID; /** * Main Application class that initializes and provides access to certain things like * logging and DB access. @@ -211,6 +211,14 @@ public class GBApplication extends Application { notificationManager.createNotificationChannel(channel); } + NotificationChannel channelHighPr = notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_HIGH_PRIORITY_ID ); + if (channelHighPr == null) { + channelHighPr = new NotificationChannel(NOTIFICATION_CHANNEL_HIGH_PRIORITY_ID, + getString(R.string.notification_channel_high_priority_name), + NotificationManager.IMPORTANCE_HIGH); + notificationManager.createNotificationChannel(channelHighPr); + } + bluetoothStateChangeReceiver = new BluetoothStateChangeReceiver(); registerReceiver(bluetoothStateChangeReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); } @@ -344,6 +352,10 @@ public class GBApplication extends Application { return VERSION.SDK_INT >= Build.VERSION_CODES.O; } + public static boolean isRunningPieOrLater() { + return VERSION.SDK_INT >= Build.VERSION_CODES.P; + } + private static boolean isPrioritySender(int prioritySenders, String number) { if (prioritySenders == Policy.PRIORITY_SENDERS_ANY) { return true; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBEnvironment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBEnvironment.java index a8e5971f3..ee16aa828 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBEnvironment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBEnvironment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBException.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBException.java index 904d7bda6..8b20613e8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBException.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBException.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java index 597ec30a0..909dddbd5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Taavi Eomäe +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Taavi Eomäe This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Logging.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Logging.java index 32dc97081..11b941e7c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Logging.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Logging.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LoggingExceptionHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LoggingExceptionHandler.java index 13febdd74..dba78d27f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LoggingExceptionHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LoggingExceptionHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer +/* Copyright (C) 2015-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/SleepAlarmWidget.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/SleepAlarmWidget.java index 69575c63d..25ba6def5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/SleepAlarmWidget.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/SleepAlarmWidget.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. @@ -121,7 +121,7 @@ public class SleepAlarmWidget extends AppWidgetProvider { context.getString(R.string.appwidget_setting_alarm, hours, minutes), Toast.LENGTH_SHORT, GB.INFO); - Alarm alarm = AlarmUtils.createSingleShot(0,true, calendar); + Alarm alarm = AlarmUtils.createSingleShot(0, true, false, calendar); ArrayList alarms = new ArrayList<>(1); alarms.add(alarm); GBApplication.deviceService().onSetAlarms(alarms); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java index b1f7e47ec..c59ad39e0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa, vanous +/* Copyright (C) 2019-2020 Andreas Shimokawa, vanous This file is part of Gadgetbridge. @@ -66,12 +66,12 @@ public class Widget extends AppWidgetProvider { return gbApp.getDeviceManager().getSelectedDevice(); } - private int[] getSteps() { + private long[] getSteps() { Context context = GBApplication.getContext(); Calendar day = GregorianCalendar.getInstance(); if (!(context instanceof GBApplication)) { - return new int[]{0, 0, 0}; + return new long[]{0, 0, 0}; } DailyTotals ds = new DailyTotals(); return ds.getDailyTotalsForAllDevices(day); @@ -114,10 +114,10 @@ public class Widget extends AppWidgetProvider { } - int[] DailyTotals = getSteps(); + long[] dailyTotals = getSteps(); - views.setTextViewText(R.id.todaywidget_steps, context.getString(R.string.widget_steps_label, (int) DailyTotals[0])); - views.setTextViewText(R.id.todaywidget_sleep, context.getString(R.string.widget_sleep_label, getHM((long) DailyTotals[1]))); + views.setTextViewText(R.id.todaywidget_steps, context.getString(R.string.widget_steps_label, dailyTotals[0])); + views.setTextViewText(R.id.todaywidget_sleep, context.getString(R.string.widget_sleep_label, getHM(dailyTotals[1]))); if (device != null) { String status = String.format("%1s", device.getStateString()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractFragmentPagerAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractFragmentPagerAdapter.java index ab28aeaa5..417c9a1a0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractFragmentPagerAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractFragmentPagerAdapter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2015-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBActivity.java index c22073d43..5ae22a227 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Lem Dulfo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragment.java index 8ceed6f57..83420b28f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, walkjivefly This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragmentActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragmentActivity.java index 6b2183d2c..1e86d0e92 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragmentActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragmentActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractListActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractListActivity.java index a5d26eb5e..dcf97ed11 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractListActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractListActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java index 15714be22..fb523fdde 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Christian +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Christian Fischer, Daniele Gobbetti, Lem Dulfo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummariesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummariesActivity.java index acb260aac..d556a49f8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummariesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummariesActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java index a5e651808..f0d88d805 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Lem Dulfo This file is part of Gadgetbridge. @@ -38,6 +38,7 @@ public class AlarmDetails extends AbstractGBActivity { private Alarm alarm; private TimePicker timePicker; private CheckedTextView cbSmartWakeup; + private CheckedTextView cbSnooze; private CheckedTextView cbMonday; private CheckedTextView cbTuesday; private CheckedTextView cbWednesday; @@ -57,6 +58,7 @@ public class AlarmDetails extends AbstractGBActivity { timePicker = findViewById(R.id.alarm_time_picker); cbSmartWakeup = findViewById(R.id.alarm_cb_smart_wakeup); + cbSnooze = findViewById(R.id.alarm_cb_snooze); cbMonday = findViewById(R.id.alarm_cb_monday); cbTuesday = findViewById(R.id.alarm_cb_tuesday); cbWednesday = findViewById(R.id.alarm_cb_wednesday); @@ -71,6 +73,11 @@ public class AlarmDetails extends AbstractGBActivity { ((CheckedTextView) v).toggle(); } }); + cbSnooze.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + ((CheckedTextView) v).toggle(); + } + }); cbMonday.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { ((CheckedTextView) v).toggle(); @@ -115,6 +122,10 @@ public class AlarmDetails extends AbstractGBActivity { int smartAlarmVisibility = supportsSmartWakeup() ? View.VISIBLE : View.GONE; cbSmartWakeup.setVisibility(smartAlarmVisibility); + cbSnooze.setChecked(alarm.getSnooze()); + int snoozeVisibility = supportsSnoozing() ? View.VISIBLE : View.GONE; + cbSnooze.setVisibility(snoozeVisibility); + cbMonday.setChecked(alarm.getRepetition(Alarm.ALARM_MON)); cbTuesday.setChecked(alarm.getRepetition(Alarm.ALARM_TUE)); cbWednesday.setChecked(alarm.getRepetition(Alarm.ALARM_WED)); @@ -133,6 +144,14 @@ public class AlarmDetails extends AbstractGBActivity { return false; } + private boolean supportsSnoozing() { + if (device != null) { + DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device); + return coordinator.supportsAlarmSnoozing(); + } + return false; + } + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { @@ -146,6 +165,7 @@ public class AlarmDetails extends AbstractGBActivity { private void updateAlarm() { alarm.setSmartWakeup(supportsSmartWakeup() && cbSmartWakeup.isChecked()); + alarm.setSnooze(supportsSnoozing() && cbSnooze.isChecked()); int repetitionMask = AlarmUtils.createRepetitionMassk(cbMonday.isChecked(), cbTuesday.isChecked(), cbWednesday.isChecked(), cbThursday.isChecked(), cbFriday.isChecked(), cbSaturday.isChecked(), cbSunday.isChecked()); alarm.setRepetition(repetitionMask); alarm.setHour(timePicker.getCurrentHour()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AndroidPairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AndroidPairingActivity.java index b8bc01f4d..d51c26aa7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AndroidPairingActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AndroidPairingActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppBlacklistActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppBlacklistActivity.java index 2d5db9c00..840c488db 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppBlacklistActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppBlacklistActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 abettenburg, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 abettenburg, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Lem Dulfo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java index f770937b3..cb2744ab8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2017-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java index 6293cb03c..a1da37366 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java @@ -1,5 +1,5 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele - Gobbetti, Lem Dulfo +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti, Lem Dulfo, vanous This file is part of Gadgetbridge. @@ -17,18 +17,23 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.os.Bundle; import android.view.MenuItem; +import androidx.annotation.NonNull; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.adapter.GBAlarmListAdapter; @@ -40,6 +45,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.User; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; @@ -59,6 +65,10 @@ public class ConfigureAlarms extends AbstractGBActivity { setContentView(R.layout.activity_configure_alarms); + IntentFilter filterLocal = new IntentFilter(); + filterLocal.addAction(DeviceService.ACTION_SAVE_ALARMS); + LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal); + gbDevice = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE); mGBAlarmListAdapter = new GBAlarmListAdapter(this); @@ -136,7 +146,7 @@ public class ConfigureAlarms extends AbstractGBActivity { } private Alarm createDefaultAlarm(@NonNull Device device, @NonNull User user, int position) { - return new Alarm(device.getId(), user.getId(), position, false, false,0, 6, 30); + return new Alarm(device.getId(), user.getId(), position, false, false, false, 0, 6, 30, false); } @Override @@ -165,4 +175,25 @@ public class ConfigureAlarms extends AbstractGBActivity { private void sendAlarmsToDevice() { GBApplication.deviceService().onSetAlarms(mGBAlarmListAdapter.getAlarmList()); } + + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + + switch (action) { + case DeviceService.ACTION_SAVE_ALARMS: { + updateAlarmsFromDB(); + break; + } + } + } + }; + + @Override + protected void onDestroy() { + LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver); + super.onDestroy(); + } + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java index 6989dffd7..1b61b4791 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Johannes Tysiak, Taavi Eomäe, vanous This file is part of Gadgetbridge. @@ -343,6 +343,8 @@ public class ControlCenterv2 extends AppCompatActivity wantedPermissions.add(Manifest.permission.READ_CONTACTS); if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_DENIED) wantedPermissions.add(Manifest.permission.CALL_PHONE); + if (ContextCompat.checkSelfPermission(this, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_DENIED) + wantedPermissions.add(Manifest.permission.ANSWER_PHONE_CALLS); if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) == PackageManager.PERMISSION_DENIED) wantedPermissions.add(Manifest.permission.READ_CALL_LOG); if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DbManagementActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DbManagementActivity.java index 65005aab4..d51a495ae 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DbManagementActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DbManagementActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Alberto, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2016-2020 Alberto, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, vanous This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java index 603816832..e2a0030f4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Frank Slezak, ivanovlev, Kasha, Lem Dulfo, Pavel Elagin, Steffen Liebergeld, vanous diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java index e5121bccc..5e7afd1f7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, boun, Carsten Pfeiffer, Daniel +/* Copyright (C) 2015-2020 Andreas Shimokawa, boun, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, JohnnySun, jonnsoft, Lem Dulfo, Taavi Eomäe, Uwe Hermann @@ -53,6 +53,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -303,7 +304,13 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView registerReceiver(bluetoothReceiver, bluetoothIntents); - startDiscovery(); + if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + GB.toast(DiscoveryActivity.this, getString(R.string.error_no_location_access), Toast.LENGTH_SHORT, GB.ERROR); + LOG.error("No permission to access coarse location!"); + checkAndRequestLocationPermission(); + } else { + startDiscovery(); + } } @Override @@ -667,6 +674,7 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView bondingDevice = deviceCandidate; break; case BluetoothDevice.BOND_BONDED: + bondingDevice = deviceCandidate; handleDeviceBonded(); break; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java index 8e586543a..1e87be20f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Lem Dulfo, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FindPhoneActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FindPhoneActivity.java index 0c74ff16c..cec7e72fe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FindPhoneActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FindPhoneActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Andreas Shimokawa, Carsten Pfeiffer, Cre3per, +/* Copyright (C) 2018-2020 Andreas Shimokawa, Carsten Pfeiffer, Cre3per, Daniele Gobbetti This file is part of Gadgetbridge. @@ -17,6 +17,7 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities; +import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -39,6 +40,7 @@ import java.io.IOException; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.util.GB; public class FindPhoneActivity extends AbstractGBActivity { @@ -84,6 +86,9 @@ public class FindPhoneActivity extends AbstractGBActivity { } }); + NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancel( GB.NOTIFICATION_ID_PHONE_FIND ); + vibrate(); playRingtone(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java index c7ea1842b..f540ead7e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Lem Dulfo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/GBActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/GBActivity.java index 4bad14daf..cec1f3b4e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/GBActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/GBActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/HeartRateUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/HeartRateUtils.java index 26340a4d8..16f9fa1bb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/HeartRateUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/HeartRateUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Dikay900 +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Dikay900 This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java index ab57fd066..bd6e40257 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/NotificationFilterActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/NotificationFilterActivity.java index edd0fc26f..905d1e762 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/NotificationFilterActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/NotificationFilterActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 abettenburg, AndrewBedscastle, Carsten Pfeiffer, +/* Copyright (C) 2018-2020 abettenburg, AndrewBedscastle, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java index 98aeb74d7..a76ab4441 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Felix Konstantin Maurer, José Rebelo, Martin, Normano64, Pavel Elagin, Sebastian Kranz, vanous diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java index a0180adc3..2716d41b8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WidgetAlarmsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WidgetAlarmsActivity.java index 359115bb3..8e01404a7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WidgetAlarmsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WidgetAlarmsActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 vanous +/* Copyright (C) 2019-2020 vanous This file is part of Gadgetbridge. @@ -135,7 +135,7 @@ public class WidgetAlarmsActivity extends Activity implements View.OnClickListen this.getString(R.string.appwidget_setting_alarm, hours, minutes), Toast.LENGTH_SHORT, GB.INFO); - Alarm alarm = AlarmUtils.createSingleShot(0, true, calendar); + Alarm alarm = AlarmUtils.createSingleShot(0, true, false, calendar); ArrayList alarms = new ArrayList<>(1); alarms.add(alarm); GBApplication.deviceService().onSetAlarms(alarms); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java index d8bb0ad8a..43d85d9dc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Konrad Iturbe, Lem Dulfo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerActivity.java index 44dc09f0c..be9bc67d9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentCache.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentCache.java index 128b08e45..6ee64434d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentCache.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentCache.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledApps.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledApps.java index 6bfaa46ae..43645d9e2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledApps.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledApps.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2016-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledWatchfaces.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledWatchfaces.java index 76fda3dc6..b2b8c0db3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledWatchfaces.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledWatchfaces.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractChartFragment.java index 8ff2df1f7..595f59b7c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractChartFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Dikay900, Pavel Elagin, vanous, walkjivefly This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java index 677f49d4e..68b9caa3c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 0nse, Alberto, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 0nse, Alberto, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin, vanous This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityAnalysis.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityAnalysis.java index cac13a2d3..3a338e99f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityAnalysis.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityAnalysis.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin, vanous, Vebryn This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivitySleepChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivitySleepChartFragment.java index 5bdd11ae8..e4af067dd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivitySleepChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivitySleepChartFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Dikay900, Pavel Elagin This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AngledLabelsChartRenderer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AngledLabelsChartRenderer.java index c6fa3e42d..8dd529dad 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AngledLabelsChartRenderer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AngledLabelsChartRenderer.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa, vanous +/* Copyright (C) 2019-2020 Andreas Shimokawa, vanous This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java index 4c1a89090..70f9bb13f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, vanous, Vebryn This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsData.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsData.java index 6a4c20888..958cb2eb5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsData.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsData.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsHost.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsHost.java index 614bc907a..59185e401 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsHost.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsHost.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, vanous +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, vanous This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsPreferencesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsPreferencesActivity.java index d4383ea2e..91d9feba4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsPreferencesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsPreferencesActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo, +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo, vanous This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/CustomBarChart.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/CustomBarChart.java index 9a80db314..b1169f636 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/CustomBarChart.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/CustomBarChart.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java index a956ad73b..2f7489c15 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Cre3per, +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Cre3per, Daniele Gobbetti, Dikay900, Pavel, Pavel Elagin This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SingleEntryValueAnimator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SingleEntryValueAnimator.java index 80122156e..93ed7699b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SingleEntryValueAnimator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SingleEntryValueAnimator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer +/* Copyright (C) 2015-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepAnalysis.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepAnalysis.java index bc32f127b..d73b2e680 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepAnalysis.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepAnalysis.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Q-er +/* Copyright (C) 2019-2020 Q-er This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepChartFragment.java index abe5de407..0c3acfbcc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepChartFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Dikay900, Pavel Elagin, Q-er, vanous This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepUtils.java index 5423cd1a9..c34446ba8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SpeedZonesFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SpeedZonesFragment.java index d7bcbe939..e0f24db43 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SpeedZonesFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SpeedZonesFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Vebryn This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/TimestampValueFormatter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/TimestampValueFormatter.java index 7a89b872f..e4603cfaa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/TimestampValueFormatter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/TimestampValueFormatter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/TrailingActivitySample.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/TrailingActivitySample.java index 06d28e45b..35a69b5ad 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/TrailingActivitySample.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/TrailingActivitySample.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java index 362863f91..48f2925d8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Pavel +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Pavel Elagin, vanous This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java index ee4e9f685..79c34fb41 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin, vanous This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsActivity.java index 62792d47d..02d05af11 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa +/* Copyright (C) 2019-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index d7d9cd7c0..a40bdf45a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa +/* Copyright (C) 2019-2020 Andreas Shimokawa This file is part of Gadgetbridge. @@ -22,4 +22,7 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_WEARLOCATION = "wearlocation"; public static final String PREF_SCREEN_ORIENTATION = "screen_orientation"; public static final String PREF_RESERVER_ALARMS_CALENDAR = "reserve_alarms_calendar"; + public static final String PREF_ALLOW_HIGH_MTU = "allow_high_mtu"; + public static final String PREF_SYNC_CALENDAR = "sync_calendar"; + public static final String PREF_USE_CUSTOM_DEVICEICON = "use_custom_deviceicon"; } \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index 85be47676..c451a03c5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa, Cre3per +/* Copyright (C) 2019-2020 Andreas Shimokawa, Cre3per This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractItemAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractItemAdapter.java index 229f259e0..58745dd10 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractItemAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractItemAdapter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/ActivitySummariesAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/ActivitySummariesAdapter.java index 2f29b3b39..6ead88b06 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/ActivitySummariesAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/ActivitySummariesAdapter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2017-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AppBlacklistAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AppBlacklistAdapter.java index 33678d51e..ad2eb3a4f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AppBlacklistAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AppBlacklistAdapter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 abettenburg, AndrewBedscastle, Carsten Pfeiffer, +/* Copyright (C) 2017-2020 abettenburg, AndrewBedscastle, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/DeviceCandidateAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/DeviceCandidateAdapter.java index 2948d0940..4857bd823 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/DeviceCandidateAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/DeviceCandidateAdapter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java index 07500a8b4..520b8cfda 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. @@ -27,12 +27,13 @@ import android.widget.CompoundButton; import android.widget.Switch; import android.widget.TextView; -import java.util.ArrayList; -import java.util.List; - import androidx.annotation.NonNull; import androidx.cardview.widget.CardView; import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; +import java.util.List; + import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; @@ -71,7 +72,7 @@ public class GBAlarmListAdapter extends RecyclerView.Adapter. */ +package nodomain.freeyourgadget.gadgetbridge.database.schema; + +import android.database.sqlite.SQLiteDatabase; + +import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.database.DBUpdateScript; +import nodomain.freeyourgadget.gadgetbridge.entities.AlarmDao; +import nodomain.freeyourgadget.gadgetbridge.entities.No1F1ActivitySampleDao; + +public class GadgetbridgeUpdate_22 implements DBUpdateScript { + @Override + public void upgradeSchema(SQLiteDatabase db) { + if (!DBHelper.existsColumn(AlarmDao.TABLENAME, AlarmDao.Properties.Unused.columnName, db)) { + String ADD_COLUMN_UNUSED = "ALTER TABLE " + AlarmDao.TABLENAME + " ADD COLUMN " + + AlarmDao.Properties.Unused.columnName + " INTEGER NOT NULL DEFAULT 0;"; + db.execSQL(ADD_COLUMN_UNUSED); + } + } + + @Override + public void downgradeSchema(SQLiteDatabase db) { + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_23.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_23.java new file mode 100644 index 000000000..dd29cdca7 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_23.java @@ -0,0 +1,40 @@ +/* Copyright (C) 2017-2020 Andreas Shimokawa, protomors + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.database.schema; + +import android.database.sqlite.SQLiteDatabase; + +import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.database.DBUpdateScript; +import nodomain.freeyourgadget.gadgetbridge.entities.AlarmDao; + +public class GadgetbridgeUpdate_23 implements DBUpdateScript { + @Override + public void upgradeSchema(SQLiteDatabase db) { + if (!DBHelper.existsColumn(AlarmDao.TABLENAME, AlarmDao.Properties.Snooze.columnName, db)) { + // Setting default value of SNOOZE column to 1 (true), so that existing MiBand2 alarms + // behave as before + String ADD_COLUMN_SNOOZE = "ALTER TABLE " + AlarmDao.TABLENAME + " ADD COLUMN " + + AlarmDao.Properties.Snooze.columnName + " INTEGER NOT NULL DEFAULT 1;"; + db.execSQL(ADD_COLUMN_SNOOZE); + } + } + + @Override + public void downgradeSchema(SQLiteDatabase db) { + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_24.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_24.java new file mode 100644 index 000000000..129d3ef40 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_24.java @@ -0,0 +1,35 @@ +/* Copyright (C) 2017-2020 Andreas Shimokawa, protomors + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.database.schema; + +import android.database.sqlite.SQLiteDatabase; + +import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.database.DBUpdateScript; +import nodomain.freeyourgadget.gadgetbridge.entities.AlarmDao; + +public class GadgetbridgeUpdate_24 implements DBUpdateScript { + @Override + public void upgradeSchema(SQLiteDatabase db) { + // Probably it isbetter to hardcode then using constants since constants could change after refactoring and potentially break migration + db.execSQL("UPDATE DEVICE SET Type=170 where (Type=80 and Manufacturer like 'Fossil%')"); + } + + @Override + public void downgradeSchema(SQLiteDatabase db) { + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/SchemaMigration.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/SchemaMigration.java index 4c60c52c8..6c78a7c1d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/SchemaMigration.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/SchemaMigration.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEvent.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEvent.java index bf971d553..aae6e4266 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEvent.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEvent.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppInfo.java index 3a50d34fa..6c99215ea 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppManagement.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppManagement.java index 8af161f63..efeaa526a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppManagement.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppManagement.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa +/* Copyright (C) 2015-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppMessage.java index 2eaf8eca7..18f444bf3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventAppMessage.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java index 6b682791d..98e9a59b3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Daniele Gobbetti, José Rebelo +/* Copyright (C) 2015-2020 Andreas Shimokawa, Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventCallControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventCallControl.java index f71735002..5975c4180 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventCallControl.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventCallControl.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa +/* Copyright (C) 2015-2020 Andreas Böhler, Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDisplayMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDisplayMessage.java index c857fbba4..87b8ae18f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDisplayMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDisplayMessage.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventFindPhone.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventFindPhone.java index a75d30858..27c3f958d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventFindPhone.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventFindPhone.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa +/* Copyright (C) 2015-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventFmFrequency.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventFmFrequency.java index 180179011..8844d0acd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventFmFrequency.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventFmFrequency.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, José Rebelo +/* Copyright (C) 2015-2020 Andreas Shimokawa, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventLEDColor.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventLEDColor.java index 9ada44418..d1fdaf09f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventLEDColor.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventLEDColor.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, José Rebelo +/* Copyright (C) 2015-2020 Andreas Shimokawa, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventMusicControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventMusicControl.java index 9d9547a0e..3fddb17af 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventMusicControl.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventMusicControl.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa +/* Copyright (C) 2015-2020 Andreas Shimokawa, vanous This file is part of Gadgetbridge. @@ -29,5 +29,7 @@ public class GBDeviceEventMusicControl extends GBDeviceEvent { PREVIOUS, VOLUMEUP, VOLUMEDOWN, + FORWARD, + REWIND } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java index 3d602adc1..c0f4e2a3b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2015-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventScreenshot.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventScreenshot.java index 489f43e8e..c0b966a1c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventScreenshot.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventScreenshot.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa +/* Copyright (C) 2015-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventSendBytes.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventSendBytes.java index d8ab677c4..a41b82966 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventSendBytes.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventSendBytes.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa +/* Copyright (C) 2015-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventVersionInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventVersionInfo.java index dc1244713..801cc78ea 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventVersionInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventVersionInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/pebble/GBDeviceEventDataLogging.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/pebble/GBDeviceEventDataLogging.java index 5eb570c6d..242d5728e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/pebble/GBDeviceEventDataLogging.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/pebble/GBDeviceEventDataLogging.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa +/* Copyright (C) 2017-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java index 6c87c43cc..eea9dd67f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo, Matthieu Baerts, Nephiel, vanous This file is part of Gadgetbridge. @@ -21,13 +21,14 @@ import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.le.ScanFilter; +import androidx.annotation.NonNull; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collection; import java.util.Collections; -import androidx.annotation.NonNull; import de.greenrobot.dao.query.QueryBuilder; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBException; @@ -40,6 +41,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DeviceAttributesDao; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; + import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getPrefs; public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { @@ -145,11 +147,17 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { return false; } + @Override + public boolean supportsAlarmSnoozing() { + return false; + } + @Override public boolean supportsMusicInfo() { return false; } + @Override public boolean supportsLedColor() { return false; } @@ -172,5 +180,4 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return null; } - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractSampleProvider.java index 2739c3de6..91a590c36 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractSampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java index 9c39aceea..4c08012bd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, JohnnySun, José Rebelo, Matthieu Baerts, Nephiel, Uwe Hermann This file is part of Gadgetbridge. @@ -201,6 +201,12 @@ public interface DeviceCoordinator { */ boolean supportsSmartWakeup(GBDevice device); + /** + * Returns true if this device/coordinator supports alarm snoozing + * @return + */ + boolean supportsAlarmSnoozing(); + /** * Returns true if the given device supports heart rate measurements. * @return diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceManager.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceManager.java index c1a6c943d..0c3208950 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceManager.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceManager.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java index fabd2273c..cfe1ed68b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo, Julien Pivotto, Kasha, Sebastian Kranz, Steffen Liebergeld, Uwe Hermann diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/InstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/InstallHandler.java index 682a32243..a1a415264 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/InstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/InstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/SampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/SampleProvider.java index 546f99140..9d3010c0a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/SampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/SampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, João Paulo Barraca This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java index 255cacdd7..e67032afe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/BipActivitySummary.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/BipActivitySummary.java index e3c8e7cba..41e11da7b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/BipActivitySummary.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/amazfitbip/BipActivitySummary.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2017-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSConstants.java index dfcb8470b..c5a82d649 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSConstants.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Gordon Williams +/* Copyright (C) 2019-2020 Gordon Williams This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java index b6a29e229..05ff9fd74 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Gordon Williams, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java index afeaa08c0..3d907fbd5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900Constants.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Andreas Böhler +/* Copyright (C) 2018-2020 Andreas Böhler based on code from BlueWatcher, https://github.com/masterjc/bluewatcher This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java index 3bd12815a..36174e84a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/casiogb6900/CasioGB6900DeviceCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Böhler, Andreas Shimokawa, Carsten +/* Copyright (C) 2016-2020 Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo based on code from BlueWatcher, https://github.com/masterjc/bluewatcher diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/EXRIZUK8Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/EXRIZUK8Coordinator.java index 21beab3d6..56ee45f12 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/EXRIZUK8Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/EXRIZUK8Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Daniele Gobbetti, João Paulo Barraca, Quallenauge +/* Copyright (C) 2017-2020 Daniele Gobbetti, João Paulo Barraca, Quallenauge This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java index 527097535..8783b9eea 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, João +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, João Paulo Barraca This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java index b9e3326d5..35dada9f5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, João Paulo Barraca, José Rebelo This file is part of Gadgetbridge. @@ -55,6 +55,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; +import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getContext; @@ -198,7 +199,9 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator { } public static byte getTimeMode(String deviceAddress) { - String tmode = GBApplication.getDeviceSpecificSharedPrefs(deviceAddress).getString(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, "24h"); + GBPrefs gbPrefs = new GBPrefs(new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress))); + + String tmode = gbPrefs.getTimeFormat(); if ("24h".equals(tmode)) { return HPlusConstants.ARG_TIMEMODE_24H; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java index bef2e2e87..a0326cb89 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti, João +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti, João Paulo Barraca This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/MakibesF68Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/MakibesF68Coordinator.java index ee5eb5b1f..5994954c7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/MakibesF68Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/MakibesF68Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Daniele Gobbetti, João Paulo Barraca, Stan Gomin +/* Copyright (C) 2017-2020 Daniele Gobbetti, João Paulo Barraca, Stan Gomin This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/Q8Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/Q8Coordinator.java index a0fa2240e..b16493852 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/Q8Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/Q8Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Daniele Gobbetti, João Paulo Barraca, tiparega +/* Copyright (C) 2017-2020 Daniele Gobbetti, João Paulo Barraca, tiparega This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/ActivateDisplayOnLift.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/ActivateDisplayOnLift.java index af72d00e5..6ea015cf7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/ActivateDisplayOnLift.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/ActivateDisplayOnLift.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, José Rebelo +/* Copyright (C) 2017-2020 Andreas Shimokawa, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/DisconnectNotificationSetting.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/DisconnectNotificationSetting.java index 3fe72861e..e754348e3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/DisconnectNotificationSetting.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/DisconnectNotificationSetting.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, José Rebelo +/* Copyright (C) 2017-2020 Andreas Shimokawa, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java index cd9bb4fce..6cd7850a0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Nephiel +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Nephiel This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java index 9f35baa1e..5a752e2b0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo, Nephiel This file is part of Gadgetbridge. @@ -323,4 +323,9 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator { public boolean supportsFindDevice() { return true; } + + @Override + public boolean supportsAlarmSnoozing() { + return true; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiFWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiFWHelper.java index c29fc6011..910b89fc9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiFWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiFWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java index b18466afc..252febdff 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, JohnnySun, +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, JohnnySun, José Rebelo, Uwe Hermann This file is part of Gadgetbridge. @@ -59,6 +59,7 @@ public class HuamiService { public static final int ALERT_LEVEL_PHONE_CALL = 2; public static final int ALERT_LEVEL_VIBRATE_ONLY = 3; + // set metric distance // set 12 hour time mode @@ -158,6 +159,9 @@ public class HuamiService { public static final byte[] COMMAND_ENABLE_DISCONNECT_NOTIFCATION = new byte[]{ENDPOINT_DISPLAY, 0x0c, 0x00, 0x01, 0, 0, 0, 0}; public static final byte[] COMMAND_DISABLE_DISCONNECT_NOTIFCATION = new byte[]{ENDPOINT_DISPLAY, 0x0c, 0x00, 0x00, 0, 0, 0, 0}; + public static final byte[] COMMAND_REQUEST_ALARMS = new byte[]{0x0d}; + public static final byte[] COMMAND_REQUEST_GPS_VERSION = new byte[]{0x0e}; + // The third byte controls the threshold, in minutes // The last 8 bytes represent 2 separate time intervals for the inactivity warnings // If there is no do not disturb interval, the last 4 bytes (the second interval) are 0 diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiWeatherConditions.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiWeatherConditions.java index 56c557586..5efc8ffee 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiWeatherConditions.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiWeatherConditions.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa +/* Copyright (C) 2017-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java index a172fb72f..c462a6cbf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java @@ -1,5 +1,5 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele - Gobbetti, João Paulo Barraca, Nephiel +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti, João Paulo Barraca, Nephiel, vanous This file is part of Gadgetbridge. @@ -81,12 +81,14 @@ public class AmazfitBipCoordinator extends HuamiCoordinator { public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_amazfitbip, + R.xml.devicesettings_timeformat, R.xml.devicesettings_wearlocation, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_disconnectnotification, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, - R.xml.devicesettings_buttonactions, + R.xml.devicesettings_buttonactions_with_longpress, R.xml.devicesettings_pairingkey }; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipFWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipFWHelper.java index fa3dbcae3..ec461ac61 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipFWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipFWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipFWInstallHandler.java index 66c9fe11b..d8cc43336 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipFWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipFWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java index d5b6878ac..e104c514e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti, João +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti, João Paulo Barraca, José Rebelo, tiparega This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteFWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteFWHelper.java index 812ce5bda..d352d5f3c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteFWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteFWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteFWInstallHandler.java index 0266eb49a..28f0b2948 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteFWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteFWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipService.java index f6e4b1e82..325ddccfc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipService.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. @@ -26,9 +26,6 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.EN public class AmazfitBipService { public static final UUID UUID_CHARACTERISTIC_WEATHER = UUID.fromString("0000000e-0000-3512-2118-0009af100700"); - // goes to UUID_CHARACTERISTIC_3_CONFIGURATION, TODO: validate this for Mi Band 2, it maybe triggers more than only GPS version... - public static final byte[] COMMAND_REQUEST_GPS_VERSION = new byte[]{0x0e}; - public static final byte COMMAND_ACTIVITY_DATA_TYPE_DEBUGLOGS = 0x07; public static final byte[] COMMAND_SET_LANGUAGE_SIMPLIFIED_CHINESE = new byte[]{ENDPOINT_DISPLAY, 0x13, 0x00, 0x00}; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java index 7b35d5a88..6c5b7e839 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti, João +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti, João Paulo Barraca, Matthieu Baerts This file is part of Gadgetbridge. @@ -85,9 +85,11 @@ public class AmazfitCorCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitcor, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_timeformat, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_disconnectnotification, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_pairingkey }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorFWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorFWHelper.java index 38730a8e9..d8eb4bf45 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorFWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorFWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorFWInstallHandler.java index 610d6f013..06b6756b6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorFWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorFWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java index e248a6f98..ba1b7027c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java index 3f59b5287..56209f6be 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti, João +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti, João Paulo Barraca, Matthieu Baerts This file is part of Gadgetbridge. @@ -87,9 +87,11 @@ public class AmazfitCor2Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitcor, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_timeformat, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_disconnectnotification, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_pairingkey }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2FWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2FWHelper.java index ef6449c92..847e372be 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2FWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2FWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2FWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2FWInstallHandler.java index 0537b9837..163164b04 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2FWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2FWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java index f58f66dd0..b4bfdcafe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti, João +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti, João Paulo Barraca, José Rebelo, tiparega This file is part of Gadgetbridge. @@ -90,8 +90,10 @@ public class AmazfitGTRCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtr, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_disconnectnotification, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_pairingkey }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRFWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRFWHelper.java index a24d8e26e..ad1999dc3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRFWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRFWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRFWInstallHandler.java index 0b997c9de..c9b65d037 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRFWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRFWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java index 1d14079c0..1c244bd6a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa, Manuel Ruß +/* Copyright (C) 2019-2020 Andreas Shimokawa, Manuel Ruß This file is part of Gadgetbridge. @@ -90,8 +90,10 @@ public class AmazfitGTSCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtr, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_disconnectnotification, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_pairingkey }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSFWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSFWHelper.java index 78a9a2c5b..96875c780 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSFWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSFWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSFWInstallHandler.java index 8b0957ddf..61e6154f1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSFWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSFWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java index 7573541f5..9db8393c6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. @@ -30,7 +30,6 @@ import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; @@ -80,6 +79,7 @@ public class MiBand2Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_miband2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_timeformat, R.xml.devicesettings_donotdisturb_withauto, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_rotatewrist_cycleinfo, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2FWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2FWHelper.java index 80a5385e9..d7887d684 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2FWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2FWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2FWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2FWInstallHandler.java index 6fb08085c..229705ca5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2FWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2FWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java index d646482a5..43475b16e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, João Paulo Barraca This file is part of Gadgetbridge. @@ -67,6 +67,11 @@ public class MiBand2HRXCoordinator extends HuamiCoordinator { return null; } + @Override + public boolean supportsAlarmSnoozing() { + return true; + } + @Override public boolean supportsHeartRateMeasurement(GBDevice device) { return false; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java index d2f23274a..3dc835b4a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. @@ -104,11 +104,13 @@ public class MiBand3Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_miband3, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, R.xml.devicesettings_nightmode, R.xml.devicesettings_donotdisturb_withauto, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_swipeunlock, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_pairingkey }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3FWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3FWHelper.java index 640cc3a37..990fa879f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3FWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3FWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3FWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3FWInstallHandler.java index b5270549c..8b3893e8e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3FWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3FWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Service.java index f4e6a5381..e2284c7e1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Service.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Service.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java index c6cf1dab4..883322d0d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, HardLight, José Rebelo This file is part of Gadgetbridge. @@ -91,12 +91,15 @@ public class MiBand4Coordinator extends HuamiCoordinator { R.xml.devicesettings_miband3, R.xml.devicesettings_wearlocation, R.xml.devicesettings_custom_emoji_font, + R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, R.xml.devicesettings_nightmode, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_swipeunlock, + R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, - R.xml.devicesettings_pairingkey + R.xml.devicesettings_pairingkey, + R.xml.devicesettings_high_mtu }; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4FWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4FWHelper.java index ed2b17821..97a460717 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4FWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4FWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4FWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4FWInstallHandler.java index f8f09a8cc..ba213f27c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4FWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4FWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java index 40ec2ad7e..47fc9261e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Andreas Shimokawa, Vadim Kaushan +/* Copyright (C) 2018-2020 Andreas Shimokawa, Vadim Kaushan This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java index fb8717b6d..7f677c193 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Vadim Kaushan This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115SampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115SampleProvider.java index 64ffc3f8c..2e109571c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115SampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115SampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Daniele Gobbetti, Vadim Kaushan +/* Copyright (C) 2018-2020 Daniele Gobbetti, Vadim Kaushan This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/itag/ITagConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/itag/ITagConstants.java new file mode 100644 index 000000000..138af862d --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/itag/ITagConstants.java @@ -0,0 +1,24 @@ +/* Copyright (C) 2020 Taavi Eomäe + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.devices.itag; + +import java.util.UUID; + +public final class ITagConstants { + public static final UUID UUID_SERVICE_BUTTON = UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb"); // Contains information about the button state + public static final UUID UUID_LINK_LOSS_ALERT_LEVEL = UUID.fromString("00002a06-0000-1000-8000-00805f9b34fb"); // Contains information about the button state +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/itag/ITagCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/itag/ITagCoordinator.java new file mode 100644 index 000000000..5a65c8ce9 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/itag/ITagCoordinator.java @@ -0,0 +1,137 @@ +/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Taavi Eomäe + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +package nodomain.freeyourgadget.gadgetbridge.devices.itag; + +import android.app.Activity; +import android.content.Context; +import android.net.Uri; + +import androidx.annotation.NonNull; + +import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; +import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; +import nodomain.freeyourgadget.gadgetbridge.entities.Device; +import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; +import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; + +public class ITagCoordinator extends AbstractDeviceCoordinator { + @Override + @NonNull + public DeviceType getSupportedType(GBDeviceCandidate candidate) { + String name = candidate.getDevice().getName(); + if (name != null && name.toLowerCase().startsWith("itag")) { // All four: iTAG, iTag, ITAG and ITag exist + return DeviceType.ITAG; + } + return DeviceType.UNKNOWN; + } + + @Override + public DeviceType getDeviceType() { + return DeviceType.ITAG; + } + + @Override + public Class getPairingActivity() { + return null; + } + + @Override + public InstallHandler findInstallHandler(Uri uri, Context context) { + return null; + } + + @Override + public boolean supportsActivityDataFetching() { + return false; + } + + @Override + public boolean supportsActivityTracking() { + return false; + } + + @Override + public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { + return null; + } + + @Override + public boolean supportsScreenshots() { + return false; + } + + @Override + public int getAlarmSlotCount() { + return 0; + } + + @Override + public boolean supportsSmartWakeup(GBDevice device) { + return false; + } + + @Override + public boolean supportsHeartRateMeasurement(GBDevice device) { + return false; + } + + @Override + public String getManufacturer() { + return "Unspecified"; //TODO: Show chip manufacturer? + } + + @Override + public boolean supportsAppsManagement() { + return false; + } + + @Override + public Class getAppsManagementActivity() { + return null; + } + + @Override + public boolean supportsCalendarEvents() { + return false; + } + + @Override + public boolean supportsRealtimeData() { + return false; //TODO: RRSI + } + + @Override + public boolean supportsWeather() { + return false; + } + + @Override + public boolean supportsFindDevice() { + return true; + } + + @Override + protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) { + // nothing to delete, yet + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/BFH16Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/BFH16Constants.java index 589344d09..c9f12e528 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/BFH16Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/BFH16Constants.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Sophanimus +/* Copyright (C) 2019-2020 Sophanimus This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/BFH16DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/BFH16DeviceCoordinator.java index 44bc84a6e..e1c08f22a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/BFH16DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/BFH16DeviceCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa, Sophanimus +/* Copyright (C) 2019-2020 Andreas Shimokawa, Sophanimus This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/JYouConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/JYouConstants.java index b18c65d85..f2e2d3cd5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/JYouConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/JYouConstants.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Sami Alaoui +/* Copyright (C) 2017-2020 Pavel Elagin, Sami Alaoui This file is part of Gadgetbridge. @@ -36,12 +36,17 @@ public final class JYouConstants { public static final byte CMD_SET_SLEEP_TIME = 0x27; public static final byte CMD_SET_DND_SETTINGS = 0x39; public static final byte CMD_SET_INACTIVITY_WARNING_TIME = 0x24; + public static final byte CMD_ACTION_HEARTRATE_SWITCH = 0x0D; public static final byte CMD_ACTION_SHOW_NOTIFICATION = 0x2C; public static final byte CMD_ACTION_REBOOT_DEVICE = 0x0E; - public static final byte RECEIVE_BATTERY_LEVEL = (byte)0xF7; + public static final byte RECEIVE_HISTORY_SLEEP_COUNT = 0x32; + public static final byte RECEIVE_BLOOD_PRESSURE = (byte) 0xE8; + public static final byte RECEIVE_WATCH_MAC = (byte)0xEC; + public static final byte RECEIVE_GET_PHOTO = (byte)0xF3; public static final byte RECEIVE_DEVICE_INFO = (byte)0xF6; + public static final byte RECEIVE_BATTERY_LEVEL = (byte)0xF7; public static final byte RECEIVE_STEPS_DATA = (byte)0xF9; public static final byte RECEIVE_HEARTRATE = (byte)0xFC; @@ -54,4 +59,4 @@ public final class JYouConstants { public static final byte ICON_TWITTER = 6; public static final byte ICON_WHATSAPP = 7; public static final byte ICON_LINE = 8; -} +} \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/JYouSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/JYouSampleProvider.java new file mode 100644 index 000000000..ecb79e67b --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/JYouSampleProvider.java @@ -0,0 +1,86 @@ +/* Copyright (C) 2018-2020 Pavel Elagin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.devices.jyou; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import de.greenrobot.dao.AbstractDao; +import de.greenrobot.dao.Property; +import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; +import nodomain.freeyourgadget.gadgetbridge.entities.JYouActivitySample; +import nodomain.freeyourgadget.gadgetbridge.entities.JYouActivitySampleDao; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; + +public class JYouSampleProvider extends AbstractSampleProvider { + + public static final int TYPE_ACTIVITY = -1; + private final float movementDivisor = 6000.0f; + private GBDevice mDevice; + private DaoSession mSession; + + public JYouSampleProvider(GBDevice device, DaoSession session) { + super(device, session); + + mSession = session; + mDevice = device; + } + + @Override + public int normalizeType(int rawType) { + return rawType; + } + + @Override + public int toRawActivityKind(int activityKind) { + return activityKind; + } + + @Override + public float normalizeIntensity(int rawIntensity) { + return rawIntensity/movementDivisor; + } + + @Override + public JYouActivitySample createActivitySample() { + return new JYouActivitySample(); + } + + @Override + public AbstractDao getSampleDao() { + return getSession().getJYouActivitySampleDao(); + } + + @Nullable + @Override + protected Property getRawKindSampleProperty() { + return JYouActivitySampleDao.Properties.RawKind; + } + + @NonNull + @Override + protected Property getTimestampSampleProperty() { + return JYouActivitySampleDao.Properties.Timestamp; + } + + @NonNull + @Override + protected Property getDeviceIdentifierSampleProperty() { + return JYouActivitySampleDao.Properties.DeviceId; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30/TeclastH30Coordinator.java similarity index 94% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30Coordinator.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30/TeclastH30Coordinator.java index 68a464af4..0b4dd5298 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30/TeclastH30Coordinator.java @@ -1,5 +1,5 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele - Gobbetti, Dougal19, José Rebelo, protomors, Sami Alaoui +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti, Dougal19, José Rebelo, Pavel Elagin, protomors, Sami Alaoui This file is part of Gadgetbridge. @@ -15,7 +15,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.devices.jyou; +package nodomain.freeyourgadget.gadgetbridge.devices.jyou.TeclastH30; import android.annotation.TargetApi; import android.app.Activity; @@ -38,6 +38,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.devices.jyou.JYouConstants; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/y5/Y5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/y5/Y5Coordinator.java new file mode 100644 index 000000000..dea3e0d96 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/y5/Y5Coordinator.java @@ -0,0 +1,149 @@ +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti, José Rebelo, ladbsoft, Pavel, Pavel Elagin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.devices.jyou.y5; + +import android.app.Activity; +import android.content.Context; +import android.net.Uri; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import de.greenrobot.dao.query.QueryBuilder; +import nodomain.freeyourgadget.gadgetbridge.GBException; +import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; +import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.devices.jyou.JYouSampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; +import nodomain.freeyourgadget.gadgetbridge.entities.Device; +import nodomain.freeyourgadget.gadgetbridge.entities.JYouActivitySampleDao; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; +import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; + +public class Y5Coordinator extends AbstractDeviceCoordinator { + @Override + protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException { + Long deviceId = device.getId(); + QueryBuilder qb = session.getJYouActivitySampleDao().queryBuilder(); + qb.where(JYouActivitySampleDao.Properties.DeviceId.eq(deviceId)).buildDelete().executeDeleteWithoutDetachingEntities(); + } + + @NonNull + @Override + public DeviceType getSupportedType(GBDeviceCandidate candidate) { + try { + String name = candidate.getDevice().getName(); + if (name != null) { + if (name.contains("Y5")) { + return DeviceType.Y5; + } + } + } catch (Exception ex) { + ex.getLocalizedMessage(); + } + return DeviceType.UNKNOWN; + } + + @Override + public DeviceType getDeviceType() { + return DeviceType.Y5; + } + + @Nullable + @Override + public Class getPairingActivity() { + return null; + } + + @Override + public boolean supportsActivityDataFetching() { + return true; + } + + @Override + public boolean supportsActivityTracking() { + return true; + } + + @Override + public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { + return new JYouSampleProvider(device, session); + } + + @Override + public InstallHandler findInstallHandler(Uri uri, Context context) { + return null; + } + + @Override + public boolean supportsScreenshots() { + return false; + } + + @Override + public int getAlarmSlotCount() { + return 3; + } + + @Override + public boolean supportsSmartWakeup(GBDevice device) { + return true; + } + + @Override + public boolean supportsHeartRateMeasurement(GBDevice device) { + return true; + } + + @Override + public String getManufacturer() { + return "Y5"; + } + + @Override + public boolean supportsAppsManagement() { + return false; + } + + @Override + public Class getAppsManagementActivity() { + return null; + } + + @Override + public boolean supportsCalendarEvents() { + return false; + } + + @Override + public boolean supportsRealtimeData() { + return true; + } + + @Override + public boolean supportsWeather() { + return false; + } + + @Override + public boolean supportsFindDevice() { + return true; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewConstants.java index a817bab31..22587c9e9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewConstants.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Daniele Gobbetti +/* Copyright (C) 2016-2020 Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java index d078f9eab..558193817 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Constants.java index 5a7440c50..1a04993da 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Constants.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa, Cre3per +/* Copyright (C) 2019-2020 Andreas Shimokawa, Cre3per This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Coordinator.java index 9702b869b..e11b45dfd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Cre3per, +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Cre3per, Daniele Gobbetti, José Rebelo, Petr Kadlec, protomors This file is part of Gadgetbridge. @@ -35,6 +35,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import de.greenrobot.dao.query.QueryBuilder; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; @@ -48,6 +49,8 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; +import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getContext; @@ -75,7 +78,9 @@ public class MakibesHR3Coordinator extends AbstractDeviceCoordinator { } public static byte getTimeMode(SharedPreferences sharedPrefs) { - String timeMode = sharedPrefs.getString(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, getContext().getString(R.string.p_timeformat_24h)); + GBPrefs gbPrefs = new GBPrefs(new Prefs(sharedPrefs)); + + String timeMode = gbPrefs.getTimeFormat(); if (timeMode.equals(getContext().getString(R.string.p_timeformat_24h))) { return MakibesHR3Constants.ARG_SET_TIMEMODE_24H; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3SampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3SampleProvider.java index 07149d188..4838ba75a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3SampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3SampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Cre3per, Daniele Gobbetti, Sebastian Kranz +/* Copyright (C) 2018-2020 Cre3per, Daniele Gobbetti, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWHelper.java index 735c4eaed..13996fd5e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java index 339031881..396766b17 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandSampleProvider.java index 1d5622ccb..d60a958b6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandSampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DateTimeDisplay.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DateTimeDisplay.java index bf653cc92..3273b4edd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DateTimeDisplay.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DateTimeDisplay.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DoNotDisturb.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DoNotDisturb.java index 448f37f99..1200c6854 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DoNotDisturb.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DoNotDisturb.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 José Rebelo +/* Copyright (C) 2017-2020 José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2SampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2SampleProvider.java index 0c62e3b2f..3e70c6fe2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2SampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2SampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java index 2d1c09414..2021dc561 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Christian +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Christian Fischer, Daniele Gobbetti, José Rebelo, Michal Novotny, Szymon Tomasz Stefanek This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java index ababb3842..65a88a483 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Christian +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Christian Fischer, Daniele Gobbetti, José Rebelo, Szymon Tomasz Stefanek This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandDateConverter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandDateConverter.java index 3283c6531..fb983d48e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandDateConverter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandDateConverter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Szymon Tomasz Stefanek This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandFWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandFWHelper.java index b81ce9c21..d53e78b8a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandFWHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandFWHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandFWInstallHandler.java index 635fbb0cf..3f5825ea7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandFWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandFWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java index 4671d5e62..c365f676a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java index bedc55cf2..874a236c0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Christian +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Christian Fischer, Daniele Gobbetti, José Rebelo, Szymon Tomasz Stefanek This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandSampleProvider.java index f3732feae..27e8b39fc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandSampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandService.java index b24d8005c..b1cb81568 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandService.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Kasha This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/UserInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/UserInfo.java index d61c1b589..6061c37e9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/UserInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/UserInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Sergey Trofimov This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java index 26114d00e..b722480f7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Uwe Hermann +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd02/MijiaLywsd02Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd02/MijiaLywsd02Coordinator.java index 1cf808534..4edc59732 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd02/MijiaLywsd02Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd02/MijiaLywsd02Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miscale2/MiScale2DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miscale2/MiScale2DeviceCoordinator.java index c042e04d4..3a599e199 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miscale2/MiScale2DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miscale2/MiScale2DeviceCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Jean-François Greffier, Vadim Kaushan This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Constants.java index e69a0fffc..14ed18c99 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Constants.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 protomors +/* Copyright (C) 2017-2020 protomors This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java index 79c5943a3..479c0c9f1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo, Petr Kadlec, protomors This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1SampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1SampleProvider.java index 3e42dd1e9..0ff8db986 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1SampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1SampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Daniele Gobbetti, protomors +/* Copyright (C) 2017-2020 Daniele Gobbetti, protomors This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWInstallHandler.java index 9f21e5cfb..5befd1312 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWInstallHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java index 35cac4dd1..37a352cff 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleColor.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleColor.java index 78b72a706..9ff1d5275 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleColor.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleColor.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa +/* Copyright (C) 2015-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java index a5380d1c0..3ef7b9ea6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo, Matthieu Baerts This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleHealthSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleHealthSampleProvider.java index 465987ce3..d72b36bca 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleHealthSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleHealthSampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleIconID.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleIconID.java index ce885da84..c824fb330 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleIconID.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleIconID.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa +/* Copyright (C) 2015-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleInstallable.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleInstallable.java index d868e08e0..f1b4b4bd5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleInstallable.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleInstallable.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMisfitSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMisfitSampleProvider.java index c9e565fcf..cfd9321a7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMisfitSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMisfitSampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMorpheuzSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMorpheuzSampleProvider.java index 1492a1a51..986cf5521 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMorpheuzSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMorpheuzSampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java index 703b98e04..ff178edb2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/STM32CRC.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/STM32CRC.java index 54249569a..e94b43440 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/STM32CRC.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/STM32CRC.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ConfigActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ConfigActivity.java index a6625f13a..ed34f3bef 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ConfigActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ConfigActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -206,8 +206,7 @@ public class ConfigActivity extends AbstractGBActivity { try { helper = new PackageConfigHelper(getApplicationContext()); list = helper.getNotificationConfigurations(); - } catch (GBException e) { - GB.log("error getting configurations", GB.ERROR, e); + } catch (Exception e) { GB.toast("error getting configurations", Toast.LENGTH_SHORT, GB.ERROR, e); list = new ArrayList<>(); } @@ -234,9 +233,7 @@ public class ConfigActivity extends AbstractGBActivity { try { helper.saveNotificationConfiguration(config); LocalBroadcastManager.getInstance(ConfigActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_NOTIFICATION_CONFIG_CHANGED)); - } catch (GBException e) { - GB.log("error saving configuration", GB.ERROR, e); - + } catch (Exception e) { GB.toast("error saving notification", Toast.LENGTH_SHORT, GB.ERROR, e); } refreshList(); @@ -262,8 +259,7 @@ public class ConfigActivity extends AbstractGBActivity { try { helper.deleteNotificationConfiguration((NotificationConfiguration) adapterView.getItemAtPosition(i)); LocalBroadcastManager.getInstance(ConfigActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_NOTIFICATION_CONFIG_CHANGED)); - } catch (GBException e) { - GB.log("error deleting configuration", GB.ERROR, e); + } catch (Exception e) { GB.toast("error deleting setting", Toast.LENGTH_SHORT, GB.ERROR, e); } refreshList(); @@ -312,7 +308,7 @@ public class ConfigActivity extends AbstractGBActivity { }); device = GBApplication.app().getDeviceManager().getSelectedDevice(); - if (device == null || device.getType() != DeviceType.FOSSILQHYBRID) { + if (device == null || device.getType() != DeviceType.FOSSILQHYBRID || device.getFirmwareVersion().charAt(2) != '0') { setSettingsError(getString(R.string.watch_not_connected)); } else { updateSettings(); @@ -414,7 +410,11 @@ public class ConfigActivity extends AbstractGBActivity { }); } - final String buttonJson = device.getDeviceInfo(FossilWatchAdapter.ITEM_BUTTONS).getDetails(); + ItemWithDetails item = device.getDeviceInfo(FossilWatchAdapter.ITEM_BUTTONS); + String buttonJson = null; + if(item != null) { + buttonJson = item.getDetails(); + } try { JSONArray buttonConfig_; if (buttonJson == null || buttonJson.isEmpty()) { @@ -476,7 +476,6 @@ public class ConfigActivity extends AbstractGBActivity { buttonLayout.addView(buttonTextView); } } catch (JSONException e) { - GB.log("error parsing button config", GB.ERROR, e); GB.toast("error parsing button config", Toast.LENGTH_LONG, GB.ERROR); } } @@ -509,8 +508,7 @@ public class ConfigActivity extends AbstractGBActivity { list.clear(); try { list.addAll(helper.getNotificationConfigurations()); - } catch (GBException e) { - GB.log("error getting configurations", GB.ERROR, e); + } catch (Exception e) { GB.toast("error getting configurations", Toast.LENGTH_SHORT, GB.ERROR, e); } // null is added to indicate the plus button added handled in PackageAdapter#getView diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HRConfigActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HRConfigActivity.java new file mode 100644 index 000000000..d782cd135 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HRConfigActivity.java @@ -0,0 +1,532 @@ +package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.util.SparseArray; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomBackgroundWidgetElement; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomTextWidgetElement; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomWidget; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomWidgetElement; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.Widget; + +import static nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.WidgetSettingsActivity.RESULT_CODE_WIDGET_DELETED; +import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_COMMAND_UPDATE_WIDGETS; + +public class HRConfigActivity extends AbstractGBActivity implements View.OnClickListener, DialogInterface.OnClickListener, AdapterView.OnItemClickListener { + private SharedPreferences sharedPreferences; + private ActionListAdapter actionListAdapter; + private WidgetListAdapter widgetListAdapter; + private ArrayList menuActions = new ArrayList<>(); + private ArrayList customWidgets = new ArrayList<>(); + + SparseArray widgetButtonsMapping = new SparseArray<>(4); + + static public final String CONFIG_KEY_Q_ACTIONS = "Q_ACTIONS"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_qhybrid_hr_settings); + + findViewById(R.id.qhybrid_action_add).setOnClickListener(this); + + sharedPreferences = GBApplication.getPrefs().getPreferences(); + + initMappings(); + loadWidgetConfigs(); + + + ListView actionListView = findViewById(R.id.qhybrid_action_list); + actionListAdapter = new ActionListAdapter(menuActions); + actionListView.setAdapter(actionListAdapter); + actionListView.setOnItemClickListener(this); + + final ListView widgetListView = findViewById(R.id.qhybrid_widget_list); + widgetListAdapter = new WidgetListAdapter(customWidgets); + widgetListView.setAdapter(widgetListAdapter); + widgetListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Widget widget = widgetListAdapter.getItem(position); + + Intent startIntent = new Intent(HRConfigActivity.this, WidgetSettingsActivity.class); + startIntent.putExtra("EXTRA_WIDGET", widget); + startIntent.putExtra("EXTRA_WIDGET_IDNEX", position); + + startActivityForResult(startIntent, 0); + } + }); + loadCustomWidgetList(); + + findViewById(R.id.qhybrid_widget_add).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent startIntent = new Intent(HRConfigActivity.this, WidgetSettingsActivity.class); + + startActivityForResult(startIntent, 0); + } + }); + + for (int i = 0; i < widgetButtonsMapping.size(); i++) { + final int widgetButtonId = widgetButtonsMapping.keyAt(i); + findViewById(widgetButtonId).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Widget.WidgetType[] types = Widget.WidgetType.values(); + final ArrayList names = new ArrayList<>(types.length); + + for (Widget.WidgetType type : types) { + names.add(getResources().getString(type.getStringResource())); + } + + for(CustomWidget customWidget : customWidgets){ + names.add(customWidget.getName()); + } + + final String[] nameStrings = names.toArray(new String[0]); + new AlertDialog.Builder(HRConfigActivity.this) + .setItems( + nameStrings, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + saveWidgetSetting(widgetButtonId, which, nameStrings); + } + } + ) + .show(); + + } + }); + } + + updateSettings(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if(data == null) return; + if (resultCode == WidgetSettingsActivity.RESULT_CODE_WIDGET_CREATED) { + CustomWidget widget = (CustomWidget) data.getExtras().get("EXTRA_WIDGET"); + this.customWidgets.add(widget); + refreshWidgetList(); + saveCustomWidgetList(); + + LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHYBRID_COMMAND_UPDATE_WIDGETS)); + } else if (resultCode == WidgetSettingsActivity.RESULT_CODE_WIDGET_UPDATED) { + CustomWidget widget = (CustomWidget) data.getExtras().get("EXTRA_WIDGET"); + int updateIndex = data.getIntExtra("EXTRA_WIDGET_IDNEX", -1); + + this.customWidgets.set(updateIndex, widget); + + refreshWidgetList(); + saveCustomWidgetList(); + + LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHYBRID_COMMAND_UPDATE_WIDGETS)); + } else if (resultCode == WidgetSettingsActivity.RESULT_CODE_WIDGET_DELETED){ + int updateIndex = data.getIntExtra("EXTRA_WIDGET_IDNEX", -1); + + this.customWidgets.remove(updateIndex); + + refreshWidgetList(); + saveCustomWidgetList(); + + LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHYBRID_COMMAND_UPDATE_WIDGETS)); + } + + } + + private void saveCustomWidgetList() { + try { + JSONArray widgetArray = new JSONArray(); + for(CustomWidget widget : customWidgets){ + JSONArray elementArray = new JSONArray(); + + for(CustomWidgetElement element : widget.getElements()){ + JSONObject elementObject = new JSONObject(); + elementObject + .put("type", element.getWidgetElementType().getJsonIdentifier()) + .put("id", element.getId()) + .put("value", element.getValue()) + .put("x", element.getX()) + .put("y", element.getY()); + elementArray.put(elementObject); + } + + JSONObject widgetObject = new JSONObject(); + widgetObject + .put("name", widget.getName()) + .put("elements", elementArray); + + widgetArray.put(widgetObject); + } + sharedPreferences.edit().putString("QHYBRID_CUSTOM_WIDGETS", widgetArray.toString()).apply(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + private void loadCustomWidgetList() { + String customWidgetJson = sharedPreferences.getString("QHYBRID_CUSTOM_WIDGETS", "[]"); + + try { + JSONArray customWidgets = new JSONArray(customWidgetJson); + this.customWidgets.clear(); + + for (int i = 0; i < customWidgets.length(); i++) { + JSONObject customWidgetObject = customWidgets.getJSONObject(i); + CustomWidget widget = new CustomWidget( + customWidgetObject.getString("name"), 0, 0, "default" // FIXME: handle force white background + ); + JSONArray elements = customWidgetObject.getJSONArray("elements"); + + for (int i2 = 0; i2 < elements.length(); i2++) { + JSONObject element = elements.getJSONObject(i2); + if (element.getString("type").equals("text")) { + widget.addElement(new CustomTextWidgetElement( + element.getString("id"), + element.getString("value"), + element.getInt("x"), + element.getInt("y") + )); + } else if (element.getString("type").equals("background")) { + widget.addElement(new CustomBackgroundWidgetElement( + element.getString("id"), + element.getString("value") + )); + } + } + + this.customWidgets.add(widget); + } + + refreshWidgetList(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + private void refreshWidgetList() { + widgetListAdapter.notifyDataSetChanged(); + } + + private void saveWidgetSetting(int buttonId, int option, String[] names) { + String jsonKey = widgetButtonsMapping.get(buttonId); + Widget.WidgetType[] types = Widget.WidgetType.values(); + String identifier = null; + if(option < types.length){ + Widget.WidgetType type = types[option]; + identifier = type.getIdentifier(); + }else{ + identifier = "custom_" + names[option]; + } + + try { + JSONObject keyConfig = new JSONObject(sharedPreferences.getString("FOSSIL_HR_WIDGETS", "{}")); + if (identifier != null) { + keyConfig.put(jsonKey, identifier); + } else { + keyConfig.remove(jsonKey); + } + sharedPreferences.edit().putString("FOSSIL_HR_WIDGETS", keyConfig.toString()).apply(); + LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(QHYBRID_COMMAND_UPDATE_WIDGETS)); + + loadWidgetConfigs(); + } catch (JSONException e) { + e.printStackTrace(); + } + + } + + + private void loadWidgetConfigs() { + try { + for (int i = 0; i < widgetButtonsMapping.size(); i++) { + ((TextView) findViewById(widgetButtonsMapping.keyAt(i))).setText(widgetButtonsMapping.valueAt(i) + " widget"); + } + + JSONObject keyConfig = new JSONObject(sharedPreferences.getString("FOSSIL_HR_WIDGETS", "{}")); + Iterator keyIterator = keyConfig.keys(); + + loop: + while (keyIterator.hasNext()) { + String position = keyIterator.next(); + + for (int widgetButtonIndex = 0; widgetButtonIndex < widgetButtonsMapping.size(); widgetButtonIndex++) { + if (position.equals(widgetButtonsMapping.valueAt(widgetButtonIndex))) { + int buttonId = widgetButtonsMapping.keyAt(widgetButtonIndex); + String function = keyConfig.getString(position); + + Widget.WidgetType[] types = Widget.WidgetType.values(); + if(function.startsWith("custom_")){ + ((TextView) findViewById(buttonId)).setText( + position + " widget: " + function.substring(7) + ); + continue loop; + } + for (int widgetIdIndex = 0; widgetIdIndex < types.length; widgetIdIndex++) { + String widgetIdMappingValue = types[widgetIdIndex].getIdentifier(); + if (widgetIdMappingValue != null && widgetIdMappingValue.equals(function)) { + ((TextView) findViewById(buttonId)).setText( + position + " widget: " + + getResources().getText( + types[widgetIdIndex].getStringResource() + ) + ); + break; + } + } + } + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + private void initMappings() { + widgetButtonsMapping.put(R.id.qhybrid_button_widget_top, "top"); + widgetButtonsMapping.put(R.id.qhybrid_button_widget_right, "right"); + widgetButtonsMapping.put(R.id.qhybrid_button_widget_bottom, "bottom"); + widgetButtonsMapping.put(R.id.qhybrid_button_widget_left, "left"); + } + + @Override + public void onClick(View v) { + if (v.getId() == R.id.qhybrid_action_add) { + final EditText input = new EditText(this); + input.setId(0); + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT); + input.setLayoutParams(lp); + + new AlertDialog.Builder(this) + .setView(input) + .setNegativeButton("cancel", null) + .setPositiveButton("ok", this) + .setTitle("create action") + .show(); + } + } + + private void updateSettings() { + JSONArray actionArray = null; + try { + actionArray = new JSONArray(sharedPreferences.getString(CONFIG_KEY_Q_ACTIONS, "[]")); + menuActions.clear(); + for (int i = 0; i < actionArray.length(); i++) + menuActions.add(new MenuAction(actionArray.getString(i))); + + actionListAdapter.notifyDataSetChanged(); + } catch (JSONException e) { + e.printStackTrace(); + } + + } + + @Override + public void onClick(DialogInterface dialog, int which) { + EditText actionEditText = ((AlertDialog) dialog).findViewById(0); + + String action = actionEditText.getText().toString(); + try { + JSONArray actionArray = new JSONArray(sharedPreferences.getString(CONFIG_KEY_Q_ACTIONS, "[]")); + actionArray.put(action); + sharedPreferences.edit().putString(CONFIG_KEY_Q_ACTIONS, actionArray.toString()).apply(); + updateSettings(); + + LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_OVERWRITE_BUTTONS)); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void onItemClick(AdapterView parent, View view, final int position, long id) { + final EditText input = new EditText(this); + input.setId(0); + TextView subject = findViewById(0); + input.setText(subject.getText()); + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT); + input.setLayoutParams(lp); + + new AlertDialog.Builder(this) + .setView(input) + .setNegativeButton("delete", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + menuActions.remove(position); + putActionItems(menuActions); + updateSettings(); + + LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_OVERWRITE_BUTTONS)); + } + }) + .setPositiveButton("ok", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + menuActions.get(position).setAction(input.getText().toString()); + putActionItems(menuActions); + updateSettings(); + + LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_OVERWRITE_BUTTONS)); + } + }) + .setTitle("edit action") + .show(); + } + + private void moveActionUp(int position){ + this.menuActions.add(position - 1, this.menuActions.remove(position)); + this.actionListAdapter.notifyDataSetChanged(); + putActionItems(menuActions); + + LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_OVERWRITE_BUTTONS)); + } + + private void moveActionDown(int position){ + this.menuActions.add(position + 1, this.menuActions.remove(position)); + this.actionListAdapter.notifyDataSetChanged(); + putActionItems(menuActions); + + LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_OVERWRITE_BUTTONS)); + } + + private void putActionItems(List actions) { + JSONArray array = new JSONArray(); + for (MenuAction action : actions) array.put(action.getAction()); + + sharedPreferences.edit().putString(CONFIG_KEY_Q_ACTIONS, array.toString()).apply(); + } + + class MenuAction { + private String action; + + public MenuAction(String action) { + this.action = action; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + } + + class WidgetListAdapter extends ArrayAdapter { + public WidgetListAdapter(@NonNull List objects) { + super(HRConfigActivity.this, 0, objects); + } + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + if (convertView == null) convertView = new TextView(getContext()); + TextView view = (TextView) convertView; + + view.setText(getItem(position).getName()); + // view.setTextColor(Color.WHITE); + view.setTextSize(25); + + return view; + } + } + + class ActionListAdapter extends ArrayAdapter { + public ActionListAdapter(@NonNull ArrayList objects) { + super(HRConfigActivity.this, 0, objects); + } + + @NonNull + @Override + public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) { + RelativeLayout layout = new RelativeLayout(getContext()); + + TextView text = new TextView(getContext()); + text.setId(0); + + text.setText(getItem(position).getAction()); + // view.setTextColor(Color.WHITE); + text.setTextSize(25); + RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + textParams.addRule(RelativeLayout.ALIGN_PARENT_START, RelativeLayout.TRUE); + layout.addView(text); + + try { + getItem(position + 1); + ImageView downView = new ImageView(getContext()); + downView.setImageResource(R.drawable.ic_arrow_upward); + downView.setRotation(180); + RelativeLayout.LayoutParams downParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT); + downParams.addRule(RelativeLayout.ALIGN_PARENT_END, RelativeLayout.TRUE); + downView.setLayoutParams(downParams); + downView.setId(2); + downView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + moveActionDown(position); + } + }); + layout.addView(downView); + }catch (IndexOutOfBoundsException e){ + // no following item + } + + if (position != 0) { + ImageView upView = new ImageView(getContext()); + upView.setImageResource(R.drawable.ic_arrow_upward); + RelativeLayout.LayoutParams upParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT); + upParams.setMarginEnd(100); + upParams.addRule(RelativeLayout.ALIGN_PARENT_END, RelativeLayout.TRUE); + upView.setLayoutParams(upParams); + upView.setId(1); + upView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + moveActionUp(position); + } + }); + layout.addView(upView); + } + + return layout; + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationConfiguration.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationConfiguration.java index d8d737545..9f77d5618 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationConfiguration.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationConfiguration.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationHRConfiguration.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationHRConfiguration.java new file mode 100644 index 000000000..03fe551a3 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationHRConfiguration.java @@ -0,0 +1,44 @@ +package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid; + +import java.io.Serializable; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.zip.CRC32; + +public class NotificationHRConfiguration implements Serializable { + private String packageName; + private long id = -1; + private byte[] packageCrc; + + public NotificationHRConfiguration(String packageName, long id) { + this.packageName = packageName; + this.id = id; + + CRC32 crc = new CRC32(); + crc.update(packageName.getBytes()); + + this.packageCrc = ByteBuffer + .allocate(4) + .order(ByteOrder.LITTLE_ENDIAN) + .putInt((int) crc.getValue()) + .array(); + } + + public NotificationHRConfiguration(String packageName, byte[] packageCrc, long id) { + this.id = id; + this.packageCrc = packageCrc; + this.packageName = packageName; + } + + public String getPackageName() { + return packageName; + } + + public long getId() { + return id; + } + + public byte[] getPackageCrc() { + return packageCrc; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/PackageConfigHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/PackageConfigHelper.java index b978398a2..1dadafce4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/PackageConfigHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/PackageConfigHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -25,9 +25,7 @@ import android.util.Log; import java.util.ArrayList; import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.GBException; -import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; -import nodomain.freeyourgadget.gadgetbridge.database.DBOpenHelper; +import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -43,11 +41,15 @@ public class PackageConfigHelper { public static final String DB_RESPECT_SILENT = "respectSilent"; - public PackageConfigHelper(Context context) throws GBException { - initDB(); + public PackageConfigHelper(Context context) { + try { + initDB(); + } catch (Exception e) { + GB.log("error getting database", GB.ERROR, e); + } } - public void saveNotificationConfiguration(NotificationConfiguration settings) throws GBException { + public void saveNotificationConfiguration(NotificationConfiguration settings) throws Exception { ContentValues values = new ContentValues(6); values.put(DB_PACKAGE, settings.getPackageName()); values.put(DB_APPNAME, settings.getAppName()); @@ -56,103 +58,99 @@ public class PackageConfigHelper { values.put(DB_VIBRATION, settings.getVibration().getValue()); values.put(DB_RESPECT_SILENT, settings.getRespectSilentMode()); - SQLiteDatabase database = GBApplication.acquireDB().getDatabase(); + try (DBHandler db = GBApplication.acquireDB()) { + SQLiteDatabase database = db.getDatabase(); - if(settings.getId() == -1) { - settings.setId(database.insert(DB_TABLE, null, values)); - }else{ - database.update(DB_TABLE, values, DB_ID + "=?", new String[]{String.valueOf(settings.getId())}); + if (settings.getId() == -1) { + settings.setId(database.insert(DB_TABLE, null, values)); + } else { + database.update(DB_TABLE, values, DB_ID + "=?", new String[]{String.valueOf(settings.getId())}); + } } - - GBApplication.releaseDB(); //LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent()); } - public ArrayList getNotificationConfigurations() throws GBException { - SQLiteDatabase database = GBApplication.acquireDB().getDatabase(); + public ArrayList getNotificationConfigurations() throws Exception { + try (DBHandler db = GBApplication.acquireDB()) { + SQLiteDatabase database = db.getDatabase(); - Cursor cursor = database.query(DB_TABLE, new String[]{"*"}, null, null, null, null, null); - - GBApplication.releaseDB(); - - int size = cursor.getCount(); - ArrayList list = new ArrayList<>(size); - if(size > 0){ - int appNamePos = cursor.getColumnIndex(DB_APPNAME); - int packageNamePos = cursor.getColumnIndex(DB_PACKAGE); - int hourPos = cursor.getColumnIndex(DB_HOUR); - int minPos = cursor.getColumnIndex(DB_MINUTE); - int silentPos = cursor.getColumnIndex(DB_RESPECT_SILENT); - int vibrationPos = cursor.getColumnIndex(DB_VIBRATION); - int idPos = cursor.getColumnIndex(DB_ID); - cursor.moveToFirst(); - do { - list.add(new NotificationConfiguration( - (short)cursor.getInt(minPos), - (short)cursor.getInt(hourPos), - cursor.getString(packageNamePos), - cursor.getString(appNamePos), - cursor.getInt(silentPos) == 1, - PlayNotificationRequest.VibrationType.fromValue((byte)cursor.getInt(vibrationPos)), - cursor.getInt(idPos) - )); - Log.d("Settings", "setting #" + cursor.getPosition() + ": " + cursor.getInt(silentPos)); - }while (cursor.moveToNext()); + try (Cursor cursor = database.query(DB_TABLE, new String[]{"*"}, null, null, null, null, null)) { + int size = cursor.getCount(); + ArrayList list = new ArrayList<>(size); + if (size > 0) { + int appNamePos = cursor.getColumnIndex(DB_APPNAME); + int packageNamePos = cursor.getColumnIndex(DB_PACKAGE); + int hourPos = cursor.getColumnIndex(DB_HOUR); + int minPos = cursor.getColumnIndex(DB_MINUTE); + int silentPos = cursor.getColumnIndex(DB_RESPECT_SILENT); + int vibrationPos = cursor.getColumnIndex(DB_VIBRATION); + int idPos = cursor.getColumnIndex(DB_ID); + cursor.moveToFirst(); + do { + list.add(new NotificationConfiguration( + (short) cursor.getInt(minPos), + (short) cursor.getInt(hourPos), + cursor.getString(packageNamePos), + cursor.getString(appNamePos), + cursor.getInt(silentPos) == 1, + PlayNotificationRequest.VibrationType.fromValue((byte) cursor.getInt(vibrationPos)), + cursor.getInt(idPos) + )); + Log.d("Settings", "setting #" + cursor.getPosition() + ": " + cursor.getInt(silentPos)); + } while (cursor.moveToNext()); + } + return list; + } } - cursor.close(); - return list; } - public NotificationConfiguration getNotificationConfiguration(String appName) throws GBException { + public NotificationConfiguration getNotificationConfiguration(String appName) throws Exception { if(appName == null) return null; - SQLiteDatabase database = GBApplication.acquireDB().getDatabase(); + try (DBHandler db = GBApplication.acquireDB()) { + SQLiteDatabase database = db.getDatabase(); - Cursor c = database.query(DB_TABLE, new String[]{"*"}, DB_APPNAME + "=?", new String[]{appName}, null, null, null); - - GBApplication.releaseDB(); - - if(c.getCount() == 0){ - c.close(); - return null; + try (Cursor c = database.query(DB_TABLE, new String[]{"*"}, DB_APPNAME + "=?", new String[]{appName}, null, null, null)) { + if (c.getCount() == 0) { + return null; + } + c.moveToFirst(); + NotificationConfiguration settings = new NotificationConfiguration( + (short) c.getInt(c.getColumnIndex(DB_MINUTE)), + (short) c.getInt(c.getColumnIndex(DB_HOUR)), + c.getString(c.getColumnIndex(DB_PACKAGE)), + c.getString(c.getColumnIndex(DB_APPNAME)), + c.getInt(c.getColumnIndex(DB_RESPECT_SILENT)) == 1, + PlayNotificationRequest.VibrationType.fromValue((byte) c.getInt(c.getColumnIndex(DB_VIBRATION))), + c.getInt(c.getColumnIndex(DB_ID)) + ); + return settings; + } } - c.moveToFirst(); - NotificationConfiguration settings = new NotificationConfiguration( - (short)c.getInt(c.getColumnIndex(DB_MINUTE)), - (short)c.getInt(c.getColumnIndex(DB_HOUR)), - c.getString(c.getColumnIndex(DB_PACKAGE)), - c.getString(c.getColumnIndex(DB_APPNAME)), - c.getInt(c.getColumnIndex(DB_RESPECT_SILENT)) == 1, - PlayNotificationRequest.VibrationType.fromValue((byte)c.getInt(c.getColumnIndex(DB_VIBRATION))), - c.getInt(c.getColumnIndex(DB_ID)) - ); - c.close(); - return settings; } - private void initDB() throws GBException { - SQLiteDatabase database = GBApplication.acquireDB().getDatabase(); + private void initDB() throws Exception { + try (DBHandler db = GBApplication.acquireDB()) { + SQLiteDatabase database = db.getDatabase(); - database.execSQL("CREATE TABLE IF NOT EXISTS notifications(" + - DB_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " + - DB_PACKAGE + " TEXT, " + - DB_VIBRATION + " INTEGER, " + - DB_MINUTE + " INTEGER DEFAULT -1, " + - DB_APPNAME + " TEXT," + - DB_RESPECT_SILENT + " INTEGER," + - DB_HOUR + " INTEGER DEFAULT -1);"); - - GBApplication.releaseDB(); + database.execSQL("CREATE TABLE IF NOT EXISTS notifications(" + + DB_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " + + DB_PACKAGE + " TEXT, " + + DB_VIBRATION + " INTEGER, " + + DB_MINUTE + " INTEGER DEFAULT -1, " + + DB_APPNAME + " TEXT," + + DB_RESPECT_SILENT + " INTEGER," + + DB_HOUR + " INTEGER DEFAULT -1);"); + } } - public void deleteNotificationConfiguration(NotificationConfiguration packageSettings) throws GBException { + public void deleteNotificationConfiguration(NotificationConfiguration packageSettings) throws Exception { Log.d("DB", "deleting id " + packageSettings.getId()); if(packageSettings.getId() == -1) return; - SQLiteDatabase database = GBApplication.acquireDB().getDatabase(); - - database.delete(DB_TABLE, DB_ID + "=?", new String[]{String.valueOf(packageSettings.getId())}); - - GBApplication.releaseDB(); + try (DBHandler db = GBApplication.acquireDB()) { + SQLiteDatabase database = db.getDatabase(); + database.delete(DB_TABLE, DB_ID + "=?", new String[]{String.valueOf(packageSettings.getId())}); + } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridAppChoserActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridAppChoserActivity.java index 0a5dc4f7b..011ca700a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridAppChoserActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridAppChoserActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -33,16 +33,15 @@ import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; + import java.util.Collections; import java.util.Comparator; import java.util.IdentityHashMap; import java.util.List; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.localbroadcastmanager.content.LocalBroadcastManager; - -import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; @@ -53,21 +52,14 @@ import static android.view.View.GONE; public class QHybridAppChoserActivity extends AbstractGBActivity { boolean hasControl = false; - PackageConfigHelper helper; + private PackageConfigHelper helper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_qhybrid_app_choser); - try { - helper = new PackageConfigHelper(getApplicationContext()); - } catch (GBException e) { - GB.log("database error", GB.ERROR, e); - GB.toast("error getting database helper", Toast.LENGTH_SHORT, GB.ERROR, e); - finish(); - return; - } + helper = new PackageConfigHelper(getApplicationContext()); final ListView appList = findViewById(R.id.qhybrid_appChooserList); final PackageManager manager = getPackageManager(); @@ -146,8 +138,7 @@ public class QHybridAppChoserActivity extends AbstractGBActivity { try { helper.saveNotificationConfiguration(config); LocalBroadcastManager.getInstance(QHybridAppChoserActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_NOTIFICATION_CONFIG_CHANGED)); - } catch (GBException e) { - GB.log("error saving config", GB.ERROR, e); + } catch (Exception e) { GB.toast("error saving configuration", Toast.LENGTH_SHORT, GB.ERROR, e); } finish(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java index ee2107f70..4f4802d9c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniel +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. @@ -19,26 +19,22 @@ package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid; import android.annotation.TargetApi; import android.app.Activity; -import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanFilter; import android.content.Context; import android.net.Uri; import android.os.Build; import android.os.ParcelUuid; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import java.util.Collection; +import java.util.Collections; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBException; +import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; @@ -48,9 +44,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; -import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; public class QHybridCoordinator extends AbstractDeviceCoordinator { @NonNull @@ -85,7 +79,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { @Override public boolean supportsActivityDataFetching() { - return true; + return false; } @Override @@ -93,6 +87,11 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { return false; } + @Override + public boolean supportsUnicodeEmojis() { + return true; + } + @Override public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { return null; @@ -108,7 +107,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { return false; } - public boolean supportsAlarmConfiguration() { + private boolean supportsAlarmConfiguration() { GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice(); if(connectedDevice == null || connectedDevice.getType() != DeviceType.FOSSILQHYBRID || connectedDevice.getState() != GBDevice.State.INITIALIZED){ return false; @@ -131,8 +130,6 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { return false; } - - @Override public String getManufacturer() { return "Fossil"; @@ -145,7 +142,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { @Override public Class getAppsManagementActivity() { - return ConfigActivity.class; + return isHybridHR() ? HRConfigActivity.class : ConfigActivity.class; } @Override @@ -160,7 +157,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { @Override public boolean supportsWeather() { - return false; + return isHybridHR(); } @Override @@ -181,5 +178,26 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator { } + @Override + public int[] getSupportedDeviceSpecificSettings(GBDevice device) { + if (isHybridHR()) { + return new int[]{ + R.xml.devicesettings_fossilhybridhr, + R.xml.devicesettings_pairingkey, + R.xml.devicesettings_custom_deviceicon + }; + } + return new int[]{ + R.xml.devicesettings_pairingkey, + R.xml.devicesettings_custom_deviceicon + }; + } + private boolean isHybridHR() { + GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice(); + if (connectedDevice != null) { + return connectedDevice.getName().startsWith("Hybrid HR"); + } + return false; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TimePicker.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TimePicker.java index 21c8b51af..51f357774 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TimePicker.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/TimePicker.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/WidgetSettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/WidgetSettingsActivity.java new file mode 100644 index 000000000..6662a1133 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/WidgetSettingsActivity.java @@ -0,0 +1,202 @@ +package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid; + +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.RadioButton; +import android.widget.RadioGroup; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; + +import java.util.List; + +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomBackgroundWidgetElement; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomTextWidgetElement; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomWidget; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomWidgetElement; + +public class WidgetSettingsActivity extends AbstractGBActivity { + private CustomWidget subject; + private WidgetElementAdapter widgetElementAdapter; + + public static final int RESULT_CODE_WIDGET_CREATED = 0; + public static final int RESULT_CODE_WIDGET_UPDATED = 1; + public static final int RESULT_CODE_WIDGET_DELETED = 2; + public static final int RESULT_CODE_CANCELED = 3; + + private int resultCode; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.qhybrid_activity_widget_settings); + + setResult(RESULT_CODE_CANCELED); + + if(getIntent().hasExtra("EXTRA_WIDGET")){ + subject = (CustomWidget) getIntent().getExtras().get("EXTRA_WIDGET"); + ((EditText) findViewById(R.id.qhybrid_widget_name)).setText(subject.getName()); + resultCode = RESULT_CODE_WIDGET_UPDATED; + }else{ + subject = new CustomWidget("", 0, 63, "default"); // FIXME: handle force white background + resultCode = RESULT_CODE_WIDGET_CREATED; + findViewById(R.id.qhybrid_widget_delete).setEnabled(false); + } + + findViewById(R.id.qhybrid_widget_save).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + subject.setName(((EditText) findViewById(R.id.qhybrid_widget_name)).getText().toString()); + + Intent resultIntent = getIntent(); + resultIntent.putExtra("EXTRA_WIDGET", WidgetSettingsActivity.this.subject); + setResult(resultCode, resultIntent); + + finish(); + } + }); + + findViewById(R.id.qhybrid_widget_delete).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + setResult(RESULT_CODE_WIDGET_DELETED, getIntent()); + + finish(); + } + }); + + widgetElementAdapter = new WidgetElementAdapter(subject.getElements()); + ListView elementList = findViewById(R.id.qhybrid_widget_elements_list); + elementList.setAdapter(widgetElementAdapter); + elementList.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + showElementDialog(widgetElementAdapter.getItem(position)); + } + }); + + findViewById(R.id.qhybrid_widget_elements_add).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showElementDialog(null); + } + }); + } + + private void showElementDialog(@Nullable final CustomWidgetElement element){ + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(WidgetSettingsActivity.this) + .setView(R.layout.qhybrid_element_popup_view); + + if(element == null) { + dialogBuilder + .setTitle("create element") + .setNegativeButton("cancel", null) + .setPositiveButton("ok", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if(((RadioButton)((AlertDialog)dialog).findViewById(R.id.qhybrid_widget_elements_type_text)).isChecked()){ + subject.addElement(new CustomTextWidgetElement( + ((EditText)((AlertDialog)dialog).findViewById(R.id.qhybrid_widget_element_id)).getText().toString(), + ((EditText)((AlertDialog)dialog).findViewById(R.id.qhybrid_widget_element_value)).getText().toString(), + CustomWidgetElement.X_CENTER, + ((RadioButton)((AlertDialog)dialog).findViewById(R.id.qhybrid_widget_elements_position_uppper)).isChecked() ? CustomTextWidgetElement.Y_UPPER_HALF : CustomTextWidgetElement.Y_LOWER_HALF + )); + }else{ + subject.addElement(new CustomBackgroundWidgetElement( + ((EditText)((AlertDialog)dialog).findViewById(R.id.qhybrid_widget_element_id)).getText().toString(), + ((EditText)((AlertDialog)dialog).findViewById(R.id.qhybrid_widget_element_value)).getText().toString() + )); + } + refreshElementsList(); + } + }); + }else{ + dialogBuilder + .setTitle("edit element") + .setNegativeButton("delete", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + WidgetSettingsActivity.this.subject.getElements().remove(element); + + refreshElementsList(); + } + }) + .setPositiveButton("ok", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + element.setId(((EditText)((AlertDialog)dialog).findViewById(R.id.qhybrid_widget_element_id)).getText().toString()); + element.setValue(((EditText)((AlertDialog)dialog).findViewById(R.id.qhybrid_widget_element_value)).getText().toString()); + element.setY(((RadioButton)((AlertDialog)dialog).findViewById(R.id.qhybrid_widget_elements_position_uppper)).isChecked() ? CustomTextWidgetElement.Y_UPPER_HALF : CustomTextWidgetElement.Y_LOWER_HALF); + element.setWidgetElementType(CustomWidgetElement.WidgetElementType.fromRadioButtonRessource(((RadioGroup)((AlertDialog)dialog).findViewById(R.id.qhybrid_widget_element_type)).getCheckedRadioButtonId())); + + refreshElementsList(); + } + }); + } + + AlertDialog dialog = dialogBuilder.show(); + + + if(element != null){ + String elementId = element.getId(); + String elementValue = element.getValue(); + CustomWidgetElement.WidgetElementType type = element.getWidgetElementType(); + + ((EditText)dialog.findViewById(R.id.qhybrid_widget_element_id)).setText(elementId); + ((EditText)dialog.findViewById(R.id.qhybrid_widget_element_value)).setText(elementValue); + ((RadioGroup)dialog.findViewById(R.id.qhybrid_widget_element_type)).check(type.getRadioButtonResource()); + ((RadioGroup)dialog.findViewById(R.id.qhybrid_widget_element_position)).check(element.getY() == CustomWidgetElement.Y_UPPER_HALF ? R.id.qhybrid_widget_elements_position_uppper : R.id.qhybrid_widget_elements_position_lower); + } + } + + private void refreshElementsList(){ + this.widgetElementAdapter.notifyDataSetChanged(); + } + + class WidgetElementAdapter extends ArrayAdapter{ + public WidgetElementAdapter(@NonNull List objects) { + super(WidgetSettingsActivity.this, 0, objects); + } + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + RelativeLayout layout = new RelativeLayout(WidgetSettingsActivity.this); + layout.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + + + TextView idView = new TextView(WidgetSettingsActivity.this); + + idView.setText(getItem(position).getId()); + // view.setTextColor(Color.WHITE); + idView.setTextSize(25); + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + params.addRule(RelativeLayout.ALIGN_PARENT_START, RelativeLayout.TRUE); + idView.setLayoutParams(params); + + TextView contentView = new TextView(WidgetSettingsActivity.this); + contentView.setText(getItem(position).getValue()); + contentView.setTextSize(25); + params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + params.addRule(RelativeLayout.ALIGN_PARENT_END, RelativeLayout.TRUE); + contentView.setLayoutParams(params); + + layout.addView(idView); + layout.addView(contentView); + + return layout; + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi1Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi1Coordinator.java index 36c1b2289..072a26277 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi1Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi1Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Daniele Gobbetti, João Paulo Barraca, José +/* Copyright (C) 2017-2020 Daniele Gobbetti, João Paulo Barraca, José Rebelo, Quallenauge This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi3Coordinator.java index 1f5b60934..7cc70a668 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/Roidmi3Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Daniele Gobbetti, João Paulo Barraca, José +/* Copyright (C) 2017-2020 Daniele Gobbetti, João Paulo Barraca, José Rebelo, tiparega This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiConst.java index e8fd99c58..d4e48c432 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiConst.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 José Rebelo +/* Copyright (C) 2018-2020 José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiCoordinator.java index 574c2f4fe..386e95408 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/roidmi/RoidmiCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java index 70cdbe1e4..acf532094 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9CalibrationActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9CalibrationActivity.java index 9b4118e93..620255adc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9CalibrationActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9CalibrationActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Daniele Gobbetti, maxirnilian +/* Copyright (C) 2018-2020 Daniele Gobbetti, maxirnilian This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9Constants.java index 90eeccb82..8450102af 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9Constants.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 maxirnilian +/* Copyright (C) 2018-2020 maxirnilian This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9DeviceCoordinator.java index 0ac3c7d1c..fdb8543cb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9DeviceCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, maxirnilian, Vadim Kaushan This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9PairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9PairingActivity.java index a0dacdf87..4712d110f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9PairingActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9PairingActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Daniele Gobbetti, maxirnilian +/* Copyright (C) 2018-2020 Daniele Gobbetti, maxirnilian This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchCoordinator.java index 3eb136d89..c3dc07df1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo, ladbsoft This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchSampleProvider.java index 978dc4ae4..9258de4e9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchSampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Daniele Gobbetti, ladbsoft, protomors +/* Copyright (C) 2017-2020 Daniele Gobbetti, ladbsoft, protomors This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java index 57e18bc62..640932b22 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 ladbsoft +/* Copyright (C) 2018-2020 ladbsoft This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java index deaf63063..52daf2bec 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeConstants.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Andreas Shimokawa, Kranz, Sebastian Kranz +/* Copyright (C) 2018-2020 Andreas Shimokawa, Kranz, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeCoordinator.java index 3ddc4cdc3..967885213 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeCoordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo, Kranz, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java index 15dbe81c2..18d1fe860 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimePreferenceActivity.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Andreas Shimokawa, Sebastian Kranz +/* Copyright (C) 2018-2020 Andreas Shimokawa, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeSampleProvider.java index 446723b3e..82ee57dad 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/zetime/ZeTimeSampleProvider.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Daniele Gobbetti, Sebastian Kranz +/* Copyright (C) 2018-2020 Daniele Gobbetti, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractActivitySample.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractActivitySample.java index 8caf49060..d33180993 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractActivitySample.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractActivitySample.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleHealthActivitySample.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleHealthActivitySample.java index 06325049e..dcb10f236 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleHealthActivitySample.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleHealthActivitySample.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleMisfitActivitySample.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleMisfitActivitySample.java index 1df22e76c..6288038ba 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleMisfitActivitySample.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleMisfitActivitySample.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleMorpheuzActivitySample.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleMorpheuzActivitySample.java index 3caf5c2a3..1d46b0b8a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleMorpheuzActivitySample.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/entities/AbstractPebbleMorpheuzActivitySample.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/ActivityTrackExporter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/ActivityTrackExporter.java index e9eab610c..cfae846df 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/ActivityTrackExporter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/ActivityTrackExporter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2017-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java index 9eae06913..33eb1bbee 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 AndrewH, Carsten Pfeiffer, Daniele Gobbetti, +/* Copyright (C) 2017-2020 AndrewH, Carsten Pfeiffer, Daniele Gobbetti, Dikay900, Nick Spacek This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmClockReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmClockReceiver.java index bba06f855..c6967054b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmClockReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmClockReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmReceiver.java index 82668b3c7..79a7c0c68 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AlarmReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2016-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AutoStartReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AutoStartReceiver.java index 02e6cb2b8..208b90b0f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AutoStartReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/AutoStartReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer, Daniele Gobbetti, Felix +/* Copyright (C) 2017-2020 Carsten Pfeiffer, Daniele Gobbetti, Felix Konstantin Maurer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothConnectReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothConnectReceiver.java index 45957bc22..c60b3ac76 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothConnectReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothConnectReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothPairingRequestReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothPairingRequestReceiver.java index 70d39648d..395d7380c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothPairingRequestReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothPairingRequestReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Daniele Gobbetti, João +/* Copyright (C) 2016-2020 Andreas Shimokawa, Daniele Gobbetti, João Paulo Barraca This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothStateChangeReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothStateChangeReceiver.java index 3a450e965..6a8ba86e1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothStateChangeReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothStateChangeReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/CMWeatherReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/CMWeatherReceiver.java index 1eb6fed89..de2fa9f3c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/CMWeatherReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/CMWeatherReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa +/* Copyright (C) 2017-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/CalendarReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/CalendarReceiver.java index c91aa523f..d7343d6cc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/CalendarReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/CalendarReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Daniel Hauck This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/LineageOsWeatherReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/LineageOsWeatherReceiver.java index d687670ac..ebecfbac8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/LineageOsWeatherReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/LineageOsWeatherReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, keeshii +/* Copyright (C) 2017-2020 Andreas Shimokawa, keeshii This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java index 86a3b65e0..a098bc826 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 andre, Andreas Shimokawa, Avamander, Carsten +/* Copyright (C) 2015-2020 andre, Andreas Shimokawa, Avamander, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java index f8232e0e2..18b2780ea 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 abettenburg, Andreas Shimokawa, AndrewBedscastle, +/* Copyright (C) 2015-2020 abettenburg, Andreas Shimokawa, AndrewBedscastle, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Frank Slezak, Hasan Ammar, José Rebelo, Julien Pivotto, Kevin Richter, Matthieu Baerts, Normano64, Steffen Liebergeld, Taavi Eomäe, veecue, Zhong Jianxin @@ -32,7 +32,6 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.media.MediaMetadata; -import android.os.Build; import android.os.Bundle; import android.os.PowerManager; import android.os.RemoteException; @@ -44,7 +43,6 @@ import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; import androidx.core.app.NotificationCompat; import androidx.core.app.RemoteInput; import androidx.localbroadcastmanager.content.LocalBroadcastManager; @@ -55,9 +53,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Objects; +import java.util.Set; +import java.util.concurrent.TimeUnit; import de.greenrobot.dao.query.Query; import nodomain.freeyourgadget.gadgetbridge.BuildConfig; @@ -71,7 +72,6 @@ import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterEntry; import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterEntryDao; import nodomain.freeyourgadget.gadgetbridge.model.AppNotificationType; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; -import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; @@ -109,9 +109,14 @@ public class NotificationListener extends NotificationListenerService { private HashMap notificationBurstPrevention = new HashMap<>(); private HashMap notificationOldRepeatPrevention = new HashMap<>(); + private static final Set GROUP_SUMMARY_WHITELIST = Collections.singleton( + "mikado.bizcalpro" + ); + public static ArrayList notificationStack = new ArrayList<>(); private long activeCallPostTime; + private int mLastCallCommand = CallSpec.CALL_UNDEFINED; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -245,28 +250,21 @@ public class NotificationListener extends NotificationListenerService { @Override public void onNotificationPosted(StatusBarNotification sbn) { - Prefs prefs = GBApplication.getPrefs(); + logNotification(sbn, true); notificationStack.remove(sbn.getPackageName()); notificationStack.add(sbn.getPackageName()); - if (GBApplication.isRunningLollipopOrLater()) { - if ("call".equals(sbn.getNotification().category) && prefs.getBoolean("notification_support_voip_calls", false)) { - handleCallNotification(sbn); - return; - } + if (shouldIgnoreNotifications()) return; + + if (shouldIgnoreSource(sbn)) { + LOG.debug("Ignoring notification source"); + return; } - if (shouldIgnore(sbn)) { - if (!"com.sec.android.app.clockpackage".equals(sbn.getPackageName())) { // workaround to allow phone alarm notification - LOG.info("Ignore notification: " + sbn.getPackageName()); // need to fix - return; - } - } + if (handleMediaSessionNotification(sbn)) return; switch (GBApplication.getGrantedInterruptionFilter()) { - case NotificationManager.INTERRUPTION_FILTER_ALL: - break; case NotificationManager.INTERRUPTION_FILTER_ALARMS: case NotificationManager.INTERRUPTION_FILTER_NONE: return; @@ -275,22 +273,38 @@ public class NotificationListener extends NotificationListenerService { return; } - String source = sbn.getPackageName().toLowerCase(); - Notification notification = sbn.getNotification(); - if (notificationOldRepeatPrevention.containsKey(source)) { - if (notification.when <= notificationOldRepeatPrevention.get(source)) { - LOG.info("NOT processing notification, already sent newer notifications from this source."); + Prefs prefs = GBApplication.getPrefs(); + if (GBApplication.isRunningLollipopOrLater()) { + if (NotificationCompat.CATEGORY_CALL.equals(sbn.getNotification().category) + && prefs.getBoolean("notification_support_voip_calls", false)) { + handleCallNotification(sbn); return; } } + if (shouldIgnoreNotification(sbn)) { + LOG.info("Ignoring notification"); + return; + } + + String source = sbn.getPackageName().toLowerCase(); + Notification notification = sbn.getNotification(); + + Long notificationOldRepeatPreventionValue = notificationOldRepeatPrevention.get(source); + if (notificationOldRepeatPreventionValue != null + && notification.when <= notificationOldRepeatPreventionValue) { + LOG.info("NOT processing notification, already sent newer notifications from this source."); + return; + } + // Ignore too frequent notifications, according to user preference - long min_timeout = (long)prefs.getInt("notifications_timeout", 0) * 1000L; - long cur_time = System.currentTimeMillis(); - if (notificationBurstPrevention.containsKey(source)) { - long last_time = notificationBurstPrevention.get(source); - if (cur_time - last_time < min_timeout) { - LOG.info("Ignoring frequent notification, last one was " + (cur_time - last_time) + "ms ago"); + long curTime = System.nanoTime(); + Long notificationBurstPreventionValue = notificationBurstPrevention.get(source); + if (notificationBurstPreventionValue != null) { + long diff = curTime - notificationBurstPreventionValue; + if (diff < TimeUnit.SECONDS.toNanos(prefs.getInt("notifications_timeout", 0))) { + LOG.info("Ignoring frequent notification, last one was " + + TimeUnit.NANOSECONDS.toMillis(diff) + "ms ago"); return; } } @@ -346,7 +360,8 @@ public class NotificationListener extends NotificationListenerService { List actions = wearableExtender.getActions(); - if (actions.size() == 0 && NotificationCompat.isGroupSummary(notification)) { //this could cause #395 to come back + if (actions.isEmpty() && NotificationCompat.isGroupSummary(notification) + && !GROUP_SUMMARY_WHITELIST.contains(source)) { //this could cause #395 to come back LOG.info("Not forwarding notification, FLAG_GROUP_SUMMARY is set and no wearable action present. Notification flags: " + notification.flags); return; } @@ -390,7 +405,7 @@ public class NotificationListener extends NotificationListenerService { mNotificationHandleLookup.add(notificationSpec.getId(), sbn.getPostTime()); // for both DISMISS and OPEN mPackageLookup.add(notificationSpec.getId(), sbn.getPackageName()); // for MUTE - notificationBurstPrevention.put(source, cur_time); + notificationBurstPrevention.put(source, curTime); if(0 != notification.when) { notificationOldRepeatPrevention.put(source, notification.when); }else { @@ -451,10 +466,21 @@ public class NotificationListener extends NotificationListenerService { } Notification noti = sbn.getNotification(); dumpExtras(noti.extras); + boolean callStarted = false; if(noti.actions != null && noti.actions.length > 0) { for (Notification.Action action : noti.actions) { LOG.info("Found call action: " + action.title); } + if (noti.actions.length == 1) { + if (mLastCallCommand == CallSpec.CALL_INCOMING) { + LOG.info("There is only one call action and previous state was CALL_INCOMING, assuming call started"); + callStarted = true; + } else { + LOG.info("There is only one call action and previous state was not CALL_INCOMING, assuming outgoing call / duplicate notification and ignoring"); + // FIXME: is there a way to detect transition CALL_OUTGOING -> CALL_START for more complete VoIP call state tracking? + return; + } + } /*try { LOG.info("Executing first action"); noti.actions[0].actionIntent.send(); @@ -476,7 +502,8 @@ public class NotificationListener extends NotificationListenerService { activeCallPostTime = sbn.getPostTime(); CallSpec callSpec = new CallSpec(); callSpec.number = number; - callSpec.command = CallSpec.CALL_INCOMING; + callSpec.command = callStarted ? CallSpec.CALL_START : CallSpec.CALL_INCOMING; + mLastCallCommand = callSpec.command; GBApplication.deviceService().onSetCallState(callSpec); } @@ -577,6 +604,11 @@ public class NotificationListener extends NotificationListenerService { return false; } + private boolean handleMediaSessionNotification(StatusBarNotification sbn) { + MediaSessionCompat.Token mediaSession = getMediaSession(sbn.getNotification()); + return mediaSession != null && handleMediaSessionNotification(mediaSession); + } + /** * Try to handle media session notifications that tell info about the current play state. * @@ -637,23 +669,30 @@ public class NotificationListener extends NotificationListenerService { } } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public void onNotificationRemoved(StatusBarNotification sbn) { - LOG.info("Notification removed: " + sbn.getPackageName() + ": " + sbn.getNotification().category); + logNotification(sbn, false); notificationStack.remove(sbn.getPackageName()); - if(Notification.CATEGORY_CALL.equals(sbn.getNotification().category) && activeCallPostTime == sbn.getPostTime()) { - activeCallPostTime = 0; - CallSpec callSpec = new CallSpec(); - callSpec.command = CallSpec.CALL_END; - GBApplication.deviceService().onSetCallState(callSpec); + if (shouldIgnoreNotifications()) return; + if (shouldIgnoreSource(sbn)) return; + + if (handleMediaSessionNotification(sbn)) return; + + if (GBApplication.isRunningLollipopOrLater()) { + if(Notification.CATEGORY_CALL.equals(sbn.getNotification().category) + && activeCallPostTime == sbn.getPostTime()) { + activeCallPostTime = 0; + CallSpec callSpec = new CallSpec(); + callSpec.command = CallSpec.CALL_END; + mLastCallCommand = callSpec.command; + GBApplication.deviceService().onSetCallState(callSpec); + } } // FIXME: DISABLED for now - if (shouldIgnore(sbn)) - return; + if (shouldIgnoreNotification(sbn)) return; Prefs prefs = GBApplication.getPrefs(); if (prefs.getBoolean("autoremove_notifications", true)) { @@ -663,6 +702,16 @@ public class NotificationListener extends NotificationListenerService { } + private void logNotification(StatusBarNotification sbn, boolean posted) { + String infoMsg = (posted ? "Notification posted" : "Notification removed") + + ": " + sbn.getPackageName(); + + if (GBApplication.isRunningLollipopOrLater()) { + infoMsg += ": " + sbn.getNotification().category; + } + + LOG.debug(infoMsg); + } private void dumpExtras(Bundle bundle) { for (String key : bundle.keySet()) { @@ -675,7 +724,7 @@ public class NotificationListener extends NotificationListenerService { } - private boolean shouldIgnore(StatusBarNotification sbn) { + private boolean shouldIgnoreNotifications() { /* * return early if DeviceCommunicationService is not running, * else the service would get started every time we get a notification. @@ -683,15 +732,16 @@ public class NotificationListener extends NotificationListenerService { * broadcast receivers because it seems to invalidate the permissions that are * necessary for NotificationListenerService */ - if (!isServiceRunning() || sbn == null) { + if (!isServiceRunning()) { + LOG.trace("Service is not running, ignoring notification"); return true; } - return shouldIgnoreSource(sbn.getPackageName()) || shouldIgnoreNotification( - sbn.getNotification(), sbn.getPackageName()); - + return false; } - private boolean shouldIgnoreSource(String source) { + private boolean shouldIgnoreSource(StatusBarNotification sbn) { + String source = sbn.getPackageName(); + Prefs prefs = GBApplication.getPrefs(); /* do not display messages from "android" @@ -725,13 +775,9 @@ public class NotificationListener extends NotificationListenerService { return false; } - private boolean shouldIgnoreNotification(Notification notification, String source) { - - MediaSessionCompat.Token mediaSession = getMediaSession(notification); - //try to handle media session notifications - if (mediaSession != null && handleMediaSessionNotification(mediaSession)) { - return true; - } + private boolean shouldIgnoreNotification(StatusBarNotification sbn) { + Notification notification = sbn.getNotification(); + String source = sbn.getPackageName(); NotificationType type = AppNotificationType.getInstance().get(source); //ignore notifications marked as LocalOnly https://developer.android.com/reference/android/app/Notification.html#FLAG_LOCAL_ONLY @@ -752,6 +798,7 @@ public class NotificationListener extends NotificationListenerService { return true; } } + return (notification.flags & Notification.FLAG_ONGOING_EVENT) == Notification.FLAG_ONGOING_EVENT; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/OmniJawsObserver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/OmniJawsObserver.java index d43b4bfbb..87fb07375 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/OmniJawsObserver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/OmniJawsObserver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2017-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java index ee271da58..eb75fb952 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java index e98189e5b..cd25c4f7c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa, Carsten +/* Copyright (C) 2015-2020 Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Johannes Tysiak, Normano64 This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java index 3185d00ce..7065c39bb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Normano64, Zhong Jianxin This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/TimeChangeReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/TimeChangeReceiver.java index 06dc6ff61..dffc3f79b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/TimeChangeReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/TimeChangeReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationConfig.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationConfig.java index c391f48c6..f495a5dbf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationConfig.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationConfig.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationReceiver.java index 6ae23406c..79b87f3fe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2015-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java index f2b04ce36..cc2724b51 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniel +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, José Rebelo, Taavi Eomäe, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceApp.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceApp.java index bf1856a94..86a924064 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceApp.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceApp.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceCandidate.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceCandidate.java index a3331ecdb..061a187ea 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceCandidate.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceCandidate.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Taavi Eomäe This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index ff938b1f9..e78bff730 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Alberto, Andreas Böhler, Andreas Shimokawa, +/* Copyright (C) 2015-2020 Alberto, Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, criogenic, Daniel Dakhno, Daniele Gobbetti, Frank Slezak, ivanovlev, José Rebelo, Julien Pivotto, Kasha, Roi Greenberg, Sebastian Kranz, Steffen Liebergeld diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBSummaryOfDay.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBSummaryOfDay.java index 680891958..877037bba 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBSummaryOfDay.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBSummaryOfDay.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer +/* Copyright (C) 2015-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityAmount.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityAmount.java index ea9ae8f81..e5e71c137 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityAmount.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityAmount.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Pavel Elagin +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Pavel Elagin This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityAmounts.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityAmounts.java index 3f337cca2..1302c48c9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityAmounts.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityAmounts.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer +/* Copyright (C) 2015-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityKind.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityKind.java index 4138fe32d..4d657fd5a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityKind.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityKind.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityPoint.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityPoint.java index 163407e27..f87ac9bbc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityPoint.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityPoint.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2017-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySample.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySample.java index 1816d9f54..e98d50bf0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySample.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySample.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummary.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummary.java index 3041acd92..1a828313d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummary.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummary.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer +/* Copyright (C) 2017-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityTrack.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityTrack.java index ea9abb097..b60986d6f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityTrack.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityTrack.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer +/* Copyright (C) 2017-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java index d1ecb3013..4d4de0925 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2016-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Alarm.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Alarm.java index 5a4c22d3d..d996bfa20 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Alarm.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Alarm.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. @@ -37,8 +37,12 @@ public interface Alarm extends Serializable { boolean getEnabled(); + boolean getUnused(); + boolean getSmartWakeup(); + boolean getSnooze(); + int getRepetition(); boolean isRepetitive(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java index 8859c8bb8..339508172 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java @@ -1,6 +1,6 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, AnthonyDiGirolamo, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, AnthonyDiGirolamo, Daniele Gobbetti, Frank Slezak, Kaz Wolfe, Kevin Richter, Lukas Veneziano, Marvin D, - Matthieu Baerts, michaelneu, NotAFIle, Tomas Radej + Matthieu Baerts, michaelneu, NotAFIle, Tomas Radej, w2q This file is part of Gadgetbridge. @@ -51,6 +51,7 @@ public class AppNotificationType extends HashMap { // Generic Calendar put("com.android.calendar", NotificationType.GENERIC_CALENDAR); + put("mikado.bizcalpro", NotificationType.BUSINESS_CALENDAR); // Google put("com.google.android.gm", NotificationType.GMAIL); @@ -63,6 +64,7 @@ public class AppNotificationType extends HashMap { // Conversations put("eu.siacs.conversations", NotificationType.CONVERSATIONS); + put("de.pixart.messenger", NotificationType.CONVERSATIONS); // Riot put("im.vector.alpha", NotificationType.RIOT); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryState.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryState.java index 691d4c3aa..7ce59226e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryState.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryState.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Daniele Gobbetti, José Rebelo +/* Copyright (C) 2015-2020 Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEventSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEventSpec.java index 8bd3af714..fbaf1db3a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEventSpec.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEventSpec.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2016-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEvents.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEvents.java index a5be446e0..2147d0232 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEvents.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEvents.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Daniel Hauck This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CallSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CallSpec.java index c3685e590..817ba872c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CallSpec.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CallSpec.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. @@ -17,7 +17,7 @@ package nodomain.freeyourgadget.gadgetbridge.model; public class CallSpec { - public static final int CALL_UNDEFINED = 1; + public static final int CALL_UNDEFINED = 0; public static final int CALL_ACCEPT = 1; public static final int CALL_INCOMING = 2; public static final int CALL_OUTGOING = 3; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CannedMessagesSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CannedMessagesSpec.java index afe2fda92..820489071 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CannedMessagesSpec.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CannedMessagesSpec.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DailyTotals.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DailyTotals.java index 8c7fbd0ca..2b35eabb4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DailyTotals.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DailyTotals.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa, vanous +/* Copyright (C) 2019-2020 Andreas Shimokawa, vanous This file is part of Gadgetbridge. @@ -40,11 +40,11 @@ public class DailyTotals { private static final Logger LOG = LoggerFactory.getLogger(DailyTotals.class); - public int[] getDailyTotalsForAllDevices(Calendar day) { + public long[] getDailyTotalsForAllDevices(Calendar day) { Context context = GBApplication.getContext(); //get today's steps for all devices in GB - int all_steps = 0; - int all_sleep = 0; + long all_steps = 0; + long all_sleep = 0; if (context instanceof GBApplication) { @@ -55,18 +55,18 @@ public class DailyTotals { if (!coordinator.supportsActivityDataFetching()) { continue; } - int[] all_daily = getDailyTotalsForDevice(device, day); + long[] all_daily = getDailyTotalsForDevice(device, day); all_steps += all_daily[0]; all_sleep += all_daily[1] + all_daily[2]; } } LOG.debug("gbwidget daily totals, all steps:" + all_steps); LOG.debug("gbwidget daily totals, all sleep:" + all_sleep); - return new int[]{all_steps, all_sleep}; + return new long[]{all_steps, all_sleep}; } - public int[] getDailyTotalsForDevice(GBDevice device, Calendar day) { + public long[] getDailyTotalsForDevice(GBDevice device, Calendar day) { try (DBHandler handler = GBApplication.acquireDB()) { ActivityAnalysis analysis = new ActivityAnalysis(); @@ -76,19 +76,19 @@ public class DailyTotals { amountsSteps = analysis.calculateActivityAmounts(getSamplesOfDay(handler, day, 0, device)); amountsSleep = analysis.calculateActivityAmounts(getSamplesOfDay(handler, day, -12, device)); - int[] Sleep = getTotalsSleepForActivityAmounts(amountsSleep); - int Steps = getTotalsStepsForActivityAmounts(amountsSteps); + long[] sleep = getTotalsSleepForActivityAmounts(amountsSleep); + long steps = getTotalsStepsForActivityAmounts(amountsSteps); - return new int[]{Steps, Sleep[0], Sleep[1]}; + return new long[]{steps, sleep[0], sleep[1]}; } catch (Exception e) { GB.toast("Error loading activity summaries.", Toast.LENGTH_SHORT, GB.ERROR, e); - return new int[]{0, 0, 0}; + return new long[]{0, 0, 0}; } } - private int[] getTotalsSleepForActivityAmounts(ActivityAmounts activityAmounts) { + private long[] getTotalsSleepForActivityAmounts(ActivityAmounts activityAmounts) { long totalSecondsDeepSleep = 0; long totalSecondsLightSleep = 0; for (ActivityAmount amount : activityAmounts.getAmounts()) { @@ -98,14 +98,14 @@ public class DailyTotals { totalSecondsLightSleep += amount.getTotalSeconds(); } } - int totalMinutesDeepSleep = (int) (totalSecondsDeepSleep / 60); - int totalMinutesLightSleep = (int) (totalSecondsLightSleep / 60); - return new int[]{totalMinutesDeepSleep, totalMinutesLightSleep}; + long totalMinutesDeepSleep = (totalSecondsDeepSleep / 60); + long totalMinutesLightSleep = (totalSecondsLightSleep / 60); + return new long[]{totalMinutesDeepSleep, totalMinutesLightSleep}; } - private int getTotalsStepsForActivityAmounts(ActivityAmounts activityAmounts) { - int totalSteps = 0; + private long getTotalsStepsForActivityAmounts(ActivityAmounts activityAmounts) { + long totalSteps = 0; for (ActivityAmount amount : activityAmounts.getAmounts()) { totalSteps += amount.getTotalSteps(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index fb48ccf8b..f46a67dd4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -1,6 +1,6 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniel +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Frank Slezak, ivanovlev, JohnnySun, José Rebelo, - Julien Pivotto, Kasha, Sebastian Kranz, Steffen Liebergeld + Julien Pivotto, Kasha, Sebastian Kranz, Steffen Liebergeld, vanous This file is part of Gadgetbridge. @@ -53,6 +53,7 @@ public interface DeviceService extends EventHandler { String ACTION_FIND_DEVICE = PREFIX + ".action.find_device"; String ACTION_SET_CONSTANT_VIBRATION = PREFIX + ".action.set_constant_vibration"; String ACTION_SET_ALARMS = PREFIX + ".action.set_alarms"; + String ACTION_SAVE_ALARMS = PREFIX + ".action.save_alarms"; String ACTION_ENABLE_REALTIME_STEPS = PREFIX + ".action.enable_realtime_steps"; String ACTION_REALTIME_SAMPLES = PREFIX + ".action.realtime_samples"; String ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT = PREFIX + ".action.realtime_hr_measurement"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java index 8491f6833..0d008dea5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -1,8 +1,8 @@ -/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa, Carsten +/* Copyright (C) 2015-2020 Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Cre3per, Daniel Dakhno, Daniele Gobbetti, Gordon Williams, Jean-François Greffier, João Paulo Barraca, José Rebelo, Kranz, ladbsoft, - Manuel Ruß, maxirnilian, protomors, Quallenauge, Sami Alaoui, Sebastian - Kranz, Sophanimus, tiparega, Vadim Kaushan + Manuel Ruß, maxirnilian, Pavel, Pavel Elagin, protomors, Quallenauge, + Sami Alaoui, Sebastian Kranz, Sophanimus, tiparega, Vadim Kaushan This file is part of Gadgetbridge. @@ -43,7 +43,6 @@ public enum DeviceType { AMAZFITBIP_LITE(17, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_amazfit_bip_lite), AMAZFITGTR(18, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_amazfit_gtr), AMAZFITGTS(19, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_amazfit_gts), - VIBRATISSIMO(20, R.drawable.ic_device_lovetoy, R.drawable.ic_device_lovetoy_disabled, R.string.devicetype_vibratissimo), LIVEVIEW(30, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_liveview), HPLUS(40, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_hplus), MAKIBESF68(41, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_makibes_f68), @@ -51,8 +50,8 @@ public enum DeviceType { Q8(43, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_q8), NO1F1(50, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_no1_f1), TECLASTH30(60, R.drawable.ic_device_h30_h10, R.drawable.ic_device_h30_h10_disabled, R.string.devicetype_teclast_h30), + Y5(61, R.drawable.ic_device_h30_h10, R.drawable.ic_device_roidmi_disabled, R.string.devicetype_y5), XWATCH(70, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_xwatch), - FOSSILQHYBRID(80, R.drawable.ic_device_zetime, R.drawable.ic_device_zetime_disabled, R.string.devicetype_qhybrid), ZETIME(80, R.drawable.ic_device_zetime, R.drawable.ic_device_zetime_disabled, R.string.devicetype_mykronoz_zetime), ID115(90, R.drawable.ic_device_h30_h10, R.drawable.ic_device_h30_h10_disabled, R.string.devicetype_id115), WATCH9(100, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_watch9), @@ -61,11 +60,14 @@ public enum DeviceType { ROIDMI(110, R.drawable.ic_device_roidmi, R.drawable.ic_device_roidmi_disabled, R.string.devicetype_roidmi), ROIDMI3(112, R.drawable.ic_device_roidmi, R.drawable.ic_device_roidmi_disabled, R.string.devicetype_roidmi3), CASIOGB6900(120, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_casiogb6900), - MISCALE2(131, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_miscale2), + MISCALE2(131, R.drawable.ic_device_miscale2, R.drawable.ic_device_miscale2_disabled, R.string.devicetype_miscale2), BFH16(140, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_bfh16), MAKIBESHR3(150, R.drawable.ic_device_default, R.drawable.ic_device_hplus_disabled, R.string.devicetype_makibes_hr3), BANGLEJS(160, R.drawable.ic_device_zetime, R.drawable.ic_device_zetime_disabled, R.string.devicetype_banglejs), + FOSSILQHYBRID(170, R.drawable.ic_device_zetime, R.drawable.ic_device_zetime_disabled, R.string.devicetype_qhybrid), MIJIA_LYWSD02(200, R.drawable.ic_device_pebble, R.drawable.ic_device_pebble_disabled, R.string.devicetype_mijia_lywsd02), + ITAG(250, R.drawable.ic_device_itag, R.drawable.ic_device_itag_disabled, R.string.devicetype_itag), + VIBRATISSIMO(300, R.drawable.ic_device_lovetoy, R.drawable.ic_device_lovetoy_disabled, R.string.devicetype_vibratissimo), TEST(1000, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_test); private final int key; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/GPSCoordinate.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/GPSCoordinate.java index a88496136..993ee1f18 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/GPSCoordinate.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/GPSCoordinate.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer +/* Copyright (C) 2017-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/GenericItem.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/GenericItem.java index c00ae2ffe..684891131 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/GenericItem.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/GenericItem.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer +/* Copyright (C) 2015-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ItemWithDetails.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ItemWithDetails.java index f592c4160..8902d4bf8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ItemWithDetails.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ItemWithDetails.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Measurement.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Measurement.java index 57aa5d141..0790a24d8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Measurement.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Measurement.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/MusicSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/MusicSpec.java index 74aaedf57..8b819e773 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/MusicSpec.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/MusicSpec.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/MusicStateSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/MusicStateSpec.java index fd180e293..23aa23593 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/MusicStateSpec.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/MusicStateSpec.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Avamander, Carsten Pfeiffer, +/* Copyright (C) 2016-2020 Andreas Shimokawa, Avamander, Carsten Pfeiffer, Daniele Gobbetti, Steffen Liebergeld This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationSpec.java index 0a2a32539..c86b21f74 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationSpec.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationSpec.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Daniele Gobbetti, Frank Slezak +/* Copyright (C) 2015-2020 Andreas Shimokawa, Daniele Gobbetti, Frank Slezak This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java index 19035556c..ba86718d8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, AnthonyDiGirolamo, Carsten +/* Copyright (C) 2015-2020 Andreas Shimokawa, AnthonyDiGirolamo, Carsten Pfeiffer, Daniele Gobbetti, Frank Slezak, Julien Pivotto, Kaz Wolfe, Kevin Richter, Lukas Veneziano diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/RecordedDataTypes.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/RecordedDataTypes.java index 2a987cae4..5b12d4caa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/RecordedDataTypes.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/RecordedDataTypes.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/SummaryOfDay.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/SummaryOfDay.java index f66c2dae6..e123e0727 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/SummaryOfDay.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/SummaryOfDay.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer +/* Copyright (C) 2015-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/TimeStamped.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/TimeStamped.java index 4a433b2c7..283bef95c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/TimeStamped.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/TimeStamped.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ValidByDate.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ValidByDate.java index 051579cda..06881f42b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ValidByDate.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ValidByDate.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java index c7f28e349..0b1eca63c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Daniele Gobbetti, Sebastian +/* Copyright (C) 2016-2020 Andreas Shimokawa, Daniele Gobbetti, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/WeatherSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/WeatherSpec.java index 3c23d9925..f8ef57d62 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/WeatherSpec.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/WeatherSpec.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index c2a822731..c3701fb5a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa, Carsten +/* Copyright (C) 2015-2020 Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo, Sebastian Kranz, Taavi Eomäe This file is part of Gadgetbridge. @@ -26,6 +26,7 @@ import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; +import android.os.Build; import android.telephony.SmsManager; import org.slf4j.Logger; @@ -67,6 +68,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.receivers.GBMusicControlRece import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_CHANNEL_HIGH_PRIORITY_ID; import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_CHANNEL_ID; // TODO: support option for a single reminder notification when notifications could not be delivered? @@ -86,6 +88,8 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { private Context context; private boolean autoReconnect; + + @Override public void setContext(GBDevice gbDevice, BluetoothAdapter btAdapter, Context context) { this.gbDevice = gbDevice; @@ -170,9 +174,7 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { LOG.info("Got GBDeviceEventFindPhone"); switch (deviceEvent.event) { case START: - Intent startIntent = new Intent(getContext(), FindPhoneActivity.class); - startIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(startIntent); + handleGBDeviceEventFindPhoneStart(); break; case STOP: Intent intent = new Intent(FindPhoneActivity.ACTION_FOUND); @@ -183,6 +185,38 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { } } + private void handleGBDeviceEventFindPhoneStart() { + if ( Build.VERSION.SDK_INT < 29 ) { // this could be used if app in foreground + Intent startIntent = new Intent(getContext(), FindPhoneActivity.class); + startIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(startIntent); + } + else { + handleGBDeviceEventFindPhoneStartNotification(); + } + } + + private void handleGBDeviceEventFindPhoneStartNotification() { + LOG.info("Got handleGBDeviceEventFindPhoneStartNotification"); + Intent intent = new Intent(context, FindPhoneActivity.class); + + PendingIntent pi = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + + NotificationCompat.Builder notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_HIGH_PRIORITY_ID ); + notification + .setSmallIcon(R.drawable.ic_notification) + .setOngoing(false) + .setFullScreenIntent(pi, true) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setAutoCancel(true) + .setContentTitle( context.getString( R.string.find_my_phone_notification ) ); + notification.setGroup("BackgroundService"); + + notificationManager.notify( GB.NOTIFICATION_ID_PHONE_FIND, notification.build()); + } + + private void handleGBDeviceEvent(GBDeviceEventMusicControl musicEvent) { Context context = getContext(); LOG.info("Got event for MUSIC_CONTROL"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 3697e9d5a..226ef468d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa, Avamander, +/* Copyright (C) 2015-2020 Andreas Böhler, Andreas Shimokawa, Avamander, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Daniel Hauck, Dikay900, Frank Slezak, ivanovlev, João Paulo Barraca, José Rebelo, Julien Pivotto, Kasha, keeshii, Martin, Matthieu Baerts, Nephiel, Sebastian Kranz, Sergey diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupport.java index 17e7f68a4..25efe4dd8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java index 0823d3d6d..0b1be165e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java @@ -1,8 +1,8 @@ -/* Copyright (C) 2015-2019 0nse, Andreas Böhler, Andreas Shimokawa, Carsten +/* Copyright (C) 2015-2020 0nse, Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Cre3per, criogenic, Daniel Dakhno, Daniele Gobbetti, Gordon Williams, Jean-François Greffier, João Paulo Barraca, José Rebelo, Kranz, ladbsoft, - Manuel Ruß, maxirnilian, protomors, Quallenauge, Sami Alaoui, Sergey Trofimov, - Sophanimus, tiparega, Vadim Kaushan + Manuel Ruß, maxirnilian, Pavel Elagin, protomors, Quallenauge, Sami Alaoui, + Sergey Trofimov, Sophanimus, tiparega, Vadim Kaushan This file is part of Gadgetbridge. @@ -44,8 +44,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitgts.Ama import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband3.MiBand3Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband4.MiBand4Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.id115.ID115Support; +import nodomain.freeyourgadget.gadgetbridge.service.devices.itag.ITagSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.jyou.BFH16DeviceSupport; -import nodomain.freeyourgadget.gadgetbridge.service.devices.jyou.TeclastH30Support; +import nodomain.freeyourgadget.gadgetbridge.service.devices.jyou.TeclastH30.TeclastH30Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.liveview.LiveviewSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.makibeshr3.MakibesHR3DeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.MiBandSupport; @@ -57,6 +58,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSuppo import nodomain.freeyourgadget.gadgetbridge.service.devices.roidmi.RoidmiSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.vibratissimo.VibratissimoSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.watch9.Watch9DeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.service.devices.jyou.y5.Y5Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.lenovo.watchxplus.WatchXPlusDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.xwatch.XWatchSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.zetime.ZeTimeDeviceSupport; @@ -207,6 +209,9 @@ public class DeviceSupportFactory { case ROIDMI3: deviceSupport = new ServiceDeviceSupport(new RoidmiSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; + case Y5: + deviceSupport = new ServiceDeviceSupport(new Y5Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); + break; case CASIOGB6900: deviceSupport = new ServiceDeviceSupport(new CasioGB6900DeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; @@ -222,6 +227,9 @@ public class DeviceSupportFactory { case MAKIBESHR3: deviceSupport = new ServiceDeviceSupport(new MakibesHR3DeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; + case ITAG: + deviceSupport = new ServiceDeviceSupport(new ITagSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); + break; case BANGLEJS: deviceSupport = new ServiceDeviceSupport(new BangleJSDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/NotificationCollectorMonitorService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/NotificationCollectorMonitorService.java index 1dc2b09f4..e3446f081 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/NotificationCollectorMonitorService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/NotificationCollectorMonitorService.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Daniele Gobbetti +/* Copyright (C) 2017-2020 Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java index 5a01596e7..5bed25f1b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniel +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, José Rebelo, Julien Pivotto, Kasha, Sebastian Kranz, Steffen Liebergeld diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java index b45e3ad4a..2632c2492 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Daniele Gobbetti, José Rebelo +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java index 14fe2659f..3d91b01f5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa, Carsten +/* Copyright (C) 2015-2020 Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, JohnnySun, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEOperation.java index 02df2c573..2bdfa58c5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniel +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractGattCallback.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractGattCallback.java index 220c3c0df..49a777c72 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractGattCallback.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractGattCallback.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer, Daniel Dakhno +/* Copyright (C) 2015-2020 Carsten Pfeiffer, Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractTransaction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractTransaction.java index ce22a57ba..375e8a42c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractTransaction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractTransaction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa, Carsten +/* Copyright (C) 2015-2020 Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLETypeConversions.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLETypeConversions.java index 4c8bb8d77..18f33f0ae 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLETypeConversions.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLETypeConversions.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Lukas Veneziano This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BTLEOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BTLEOperation.java index 1f6faf9af..0e1ebd7ce 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BTLEOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BTLEOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BleNamesResolver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BleNamesResolver.java index f8451a330..8ba97fbc6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BleNamesResolver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BleNamesResolver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, João +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, João Paulo Barraca, JohnnySun This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEAction.java index 3e1ea2604..50549d001 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Uwe Hermann +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java index 1546b8302..42b936bb2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa, Carsten +/* Copyright (C) 2015-2020 Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Cre3per, Daniel Dakhno, Daniele Gobbetti, Sergey Trofimov, Uwe Hermann @@ -265,9 +265,6 @@ public final class BtLEQueue { mGbDevice.setState(newState); mGbDevice.sendDeviceUpdateIntent(mContext); - if (mConnectionLatch != null && newState == State.CONNECTED) { - mConnectionLatch.countDown(); - } } public void disconnect() { @@ -516,6 +513,9 @@ public final class BtLEQueue { // only propagate the successful event getCallbackToUse().onServicesDiscovered(gatt); } + if (mConnectionLatch != null) { + mConnectionLatch.countDown(); + } } else { LOG.warn("onServicesDiscovered received: " + status); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEServerAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEServerAction.java index 3ac0d4965..5dc8383fa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEServerAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEServerAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa, Carsten +/* Copyright (C) 2015-2020 Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCharacteristic.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCharacteristic.java index a9669a642..771daeb61 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCharacteristic.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCharacteristic.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2015-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattDescriptor.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattDescriptor.java index 8a92860ff..3a61ac593 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattDescriptor.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattDescriptor.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Daniele Gobbetti +/* Copyright (C) 2015-2020 Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattListenerAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattListenerAction.java index d00165778..57d174e17 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattListenerAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattListenerAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Carsten Pfeiffer +/* Copyright (C) 2018-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattServerCallback.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattServerCallback.java index 588a7dd3b..e37e2e7ad 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattServerCallback.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattServerCallback.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Böhler +/* Copyright (C) 2019-2020 Andreas Böhler This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattService.java index 8ced4b8fd..25f313d93 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattService.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2015-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/ServerTransaction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/ServerTransaction.java index 70c27bd6d..9a20f3e94 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/ServerTransaction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/ServerTransaction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa, Carsten +/* Copyright (C) 2015-2020 Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/ServerTransactionBuilder.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/ServerTransactionBuilder.java index 43b926233..1d653cc6a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/ServerTransactionBuilder.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/ServerTransactionBuilder.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Böhler +/* Copyright (C) 2019-2020 Andreas Böhler This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/Transaction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/Transaction.java index 11de807bd..60c355989 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/Transaction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/Transaction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa, Carsten +/* Copyright (C) 2015-2020 Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/TransactionBuilder.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/TransactionBuilder.java index ea1874d8d..cf900caac 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/TransactionBuilder.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/TransactionBuilder.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniel +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbortTransactionAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbortTransactionAction.java index 7d1a71d24..cb7b592f8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbortTransactionAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbortTransactionAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbstractGattListenerWriteAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbstractGattListenerWriteAction.java index 47094693b..0521c01dd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbstractGattListenerWriteAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/AbstractGattListenerWriteAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Carsten Pfeiffer +/* Copyright (C) 2018-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/CheckInitializedAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/CheckInitializedAction.java index aeb5a9b09..620f5c27d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/CheckInitializedAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/CheckInitializedAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ConditionalWriteAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ConditionalWriteAction.java index 1a6f5be93..f1cbe5045 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ConditionalWriteAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ConditionalWriteAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/NotifyAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/NotifyAction.java index 45b86a5b4..97072b431 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/NotifyAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/NotifyAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/PlainAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/PlainAction.java index f802352a3..752ce8fab 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/PlainAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/PlainAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadAction.java index 742cc695f..686abc3c2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ReadAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestMtuAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestMtuAction.java index 60fc338ce..0a24e62d1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestMtuAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/RequestMtuAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ServerResponseAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ServerResponseAction.java index 302fd9fe0..b7816c44a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ServerResponseAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/ServerResponseAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Böhler +/* Copyright (C) 2019-2020 Andreas Böhler This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceBusyAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceBusyAction.java index 384c7d584..ce1fb1287 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceBusyAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceBusyAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceStateAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceStateAction.java index 334e7432f..26566e3ce 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceStateAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetDeviceStateAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetProgressAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetProgressAction.java index ccd396df8..e8d429b88 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetProgressAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/SetProgressAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WaitAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WaitAction.java index e3b40bcdb..efd1ca511 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WaitAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WaitAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WriteAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WriteAction.java index eedb4c320..fd6651df0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WriteAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/WriteAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/AbstractBleProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/AbstractBleProfile.java index b057b028b..93c47b2e6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/AbstractBleProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/AbstractBleProfile.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/IntentListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/IntentListener.java index 29b192e51..b81ed3b06 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/IntentListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/IntentListener.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Carsten Pfeiffer +/* Copyright (C) 2018-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/ValueDecoder.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/ValueDecoder.java index 0432d475c..ec17c616f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/ValueDecoder.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/ValueDecoder.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java index 8787af3d5..4bf8f54c0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Uwe Hermann +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertLevel.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertLevel.java index 2d8bc99a1..e68a7bf3d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertLevel.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertLevel.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java index b800e803f..2734b42ff 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java index fab79f146..c38a9dcbe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertStatus.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertStatus.java index c377ee47b..5f9d49734 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertStatus.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertStatus.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java index 7f630c9fb..733616eb2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer +/* Copyright (C) 2017-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/NewAlert.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/NewAlert.java index 4b38f3546..28e6f3de0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/NewAlert.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/NewAlert.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/OverflowStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/OverflowStrategy.java index d28e98136..7fd1b7fcf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/OverflowStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/OverflowStrategy.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer +/* Copyright (C) 2017-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/SupportedNewAlertCategory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/SupportedNewAlertCategory.java index 9059c935a..bb83e7adf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/SupportedNewAlertCategory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/SupportedNewAlertCategory.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Uwe Hermann +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/battery/BatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/battery/BatteryInfo.java index 856d3c2f8..09ff1ae5a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/battery/BatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/battery/BatteryInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/battery/BatteryInfoProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/battery/BatteryInfoProfile.java index 062614a33..da320efd5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/battery/BatteryInfoProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/battery/BatteryInfoProfile.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfo.java index fac22020c..f1833b3ac 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfoProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfoProfile.java index e72f21506..8f3fe4b3d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfoProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfoProfile.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/BodySensorLocation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/BodySensorLocation.java index 552be0412..2d0bf81b8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/BodySensorLocation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/BodySensorLocation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Uwe Hermann +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/HeartRateProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/HeartRateProfile.java index 508636ff2..e66a16af4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/HeartRateProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/HeartRateProfile.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java index ccb2ce3ae..222cdd498 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa, Gordon Williams +/* Copyright (C) 2019-2020 Andreas Shimokawa, Gordon Williams This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java index d42233a0f..89d7759ca 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioGB6900DeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Andreas Böhler, Sebastian Kranz +/* Copyright (C) 2018-2020 Andreas Böhler, Sebastian Kranz based on code from BlueWatcher, https://github.com/masterjc/bluewatcher This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioHandlerThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioHandlerThread.java index 63243602c..379db068b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioHandlerThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/CasioHandlerThread.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Böhler, Daniele Gobbetti +/* Copyright (C) 2019-2020 Andreas Böhler, Daniele Gobbetti based on code from BlueWatcher, https://github.com/masterjc/bluewatcher This file is part of Gadgetbridge. @@ -30,11 +30,11 @@ import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread; public class CasioHandlerThread extends GBDeviceIoThread { private static final Logger LOG = LoggerFactory.getLogger(CasioHandlerThread.class); + private static final int TX_PERIOD = 60; private boolean mQuit = false; private CasioGB6900DeviceSupport mDeviceSupport; private final Object waitObject = new Object(); - private int TX_PERIOD = 60; private Calendar mTxTime = GregorianCalendar.getInstance(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/operations/InitOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/operations/InitOperation.java index 749d05d77..a7f7950b4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/operations/InitOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casiogb6900/operations/InitOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Böhler +/* Copyright (C) 2019-2020 Andreas Böhler This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/common/SimpleNotification.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/common/SimpleNotification.java index 82d3924e4..1a049227e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/common/SimpleNotification.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/common/SimpleNotification.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecord.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecord.java index 294501958..b88e9a0b0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecord.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecord.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 João Paulo Barraca +/* Copyright (C) 2017-2020 João Paulo Barraca This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySlot.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySlot.java index ddf7ab837..0ed86eade 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySlot.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySlot.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, João Paulo Barraca +/* Copyright (C) 2017-2020 Andreas Shimokawa, João Paulo Barraca This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySummary.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySummary.java index fd17acb23..1a5bf4720 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySummary.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordDaySummary.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 João Paulo Barraca +/* Copyright (C) 2017-2020 João Paulo Barraca This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordRealtime.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordRealtime.java index 09f9a5db9..4b0e6d356 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordRealtime.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordRealtime.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Daniele Gobbetti, João Paulo Barraca +/* Copyright (C) 2017-2020 Daniele Gobbetti, João Paulo Barraca This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordSleep.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordSleep.java index fef27f1ae..89f3e58f3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordSleep.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordSleep.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 João Paulo Barraca +/* Copyright (C) 2017-2020 João Paulo Barraca This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java index 896e06d6e..452286466 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Daniele Gobbetti, João Paulo Barraca +/* Copyright (C) 2017-2020 Daniele Gobbetti, João Paulo Barraca This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java index 2c0f43101..118693243 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Alberto, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2016-2020 Alberto, Andreas Shimokawa, Carsten Pfeiffer, ivanovlev, João Paulo Barraca, Pavel Motyrev, Quallenauge, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/AbstractHuamiOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/AbstractHuamiOperation.java index 05e070051..077a39f40 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/AbstractHuamiOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/AbstractHuamiOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiActivityDetailsParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiActivityDetailsParser.java index aa2d978be..6e8b93f13 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiActivityDetailsParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiActivityDetailsParser.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, AndrewH, Carsten Pfeiffer, +/* Copyright (C) 2017-2020 Andreas Shimokawa, AndrewH, Carsten Pfeiffer, szilardx This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiBatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiBatteryInfo.java index 21a8f0e42..047d6870d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiBatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiBatteryInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java index 415d45ff9..7242a6687 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. @@ -30,5 +30,6 @@ public class HuamiDeviceEvent { public static final byte BUTTON_PRESSED_LONG = 0x0b; public static final byte TICK_30MIN = 0x0e; // unsure public static final byte FIND_PHONE_STOP = 0x0f; + public static final byte MTU_REQUEST = 0x16; public static final byte MUSIC_CONTROL = (byte) 0xfe; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiFirmwareInfo.java index 681c4bd93..e6e715970 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa +/* Copyright (C) 2017-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiFirmwareType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiFirmwareType.java index 36eba0bfe..7bf09e35a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiFirmwareType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiFirmwareType.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiIcon.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiIcon.java index 5a572d17e..9c907c973 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiIcon.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiIcon.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti, Lukas +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti, Lukas Veneziano This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSportsActivityType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSportsActivityType.java index bd08fd488..c49659d80 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSportsActivityType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSportsActivityType.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index ef827101e..6069ae144 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -1,6 +1,6 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Christian +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Christian Fischer, Daniele Gobbetti, JohnnySun, José Rebelo, Julien Pivotto, Kasha, - Michal Novotny, Sebastian Kranz, Sergey Trofimov, Steffen Liebergeld + Michal Novotny, Sebastian Kranz, Sergey Trofimov, Steffen Liebergeld, vanous This file is part of Gadgetbridge. @@ -25,7 +25,6 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.net.Uri; -import android.text.format.DateFormat; import android.widget.Toast; import androidx.localbroadcastmanager.content.LocalBroadcastManager; @@ -55,7 +54,6 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity; -import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; @@ -130,11 +128,18 @@ import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol; import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; import nodomain.freeyourgadget.gadgetbridge.util.Version; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_ALLOW_HIGH_MTU; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DATEFORMAT; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_RESERVER_ALARMS_CALENDAR; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SYNC_CALENDAR; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TIMEFORMAT; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_WEARLOCATION; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_COUNT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_PROFILE; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.VIBRATION_COUNT; @@ -143,6 +148,7 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ge import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.getNotificationPrefStringValue; import static nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL; + public class HuamiSupport extends AbstractBTLEDeviceSupport { // We introduce key press counter for notification purposes @@ -150,6 +156,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { private static int currentButtonPressCount = 0; private static long currentButtonPressTime = 0; private static long currentButtonTimerActivationTime = 0; + private Timer buttonActionTimer = null; private static final Logger LOG = LoggerFactory.getLogger(HuamiSupport.class); private final DeviceInfoProfile deviceInfoProfile; @@ -164,7 +171,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { }; private BluetoothGattCharacteristic characteristicHRControlPoint; - protected BluetoothGattCharacteristic characteristicChunked; + private BluetoothGattCharacteristic characteristicChunked; private boolean needsAuth; private volatile boolean telephoneRinging; @@ -181,6 +188,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { private MusicSpec bufferMusicSpec = null; private MusicStateSpec bufferMusicStateSpec = null; private boolean heartRateNotifyEnabled; + private int mMTU = 23; public HuamiSupport() { this(LOG); @@ -293,15 +301,16 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { builder.notify(getCharacteristic(GattService.UUID_SERVICE_CURRENT_TIME), enable); // Notify CHARACTERISTIC9 to receive random auth code builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUTH), enable); + return this; } public HuamiSupport enableFurtherNotifications(TransactionBuilder builder, boolean enable) { builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), enable); builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_6_BATTERY_INFO), enable); - builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_DEVICEEVENT), enable); builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUDIO), enable); builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUDIODATA), enable); + builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_DEVICEEVENT), enable); return this; } @@ -729,7 +738,13 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { TransactionBuilder builder = performInitialized("Set date and time"); setCurrentTimeWithService(builder); //TODO: once we have a common strategy for sending events (e.g. EventHandler), remove this call from here. Meanwhile it does no harm. - sendCalendarEvents(builder); + // = we should genaralize the pebble calender code + if (characteristicChunked == null) { // all except Mi Band 2 + sendCalendarEvents(builder); + } + else { + sendCalendarEventsAsReminder(builder); + } builder.queue(getQueue()); } catch (IOException ex) { LOG.error("Unable to set time on Huami device", ex); @@ -810,7 +825,6 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } - private void sendMusicStateToDevice() { if (characteristicChunked == null) { return; @@ -1102,6 +1116,23 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { if (currentButtonTimerActivationTime != currentButtonPressTime) { return; } + //handle user events settings. 0 is long press, rest are button_id 1-3 + switch (currentButtonActionId) { + case 0: + handleMediaButton(prefs.getString("button_long_press_action_selection","UNKNOWN")); + break; + case 1: + handleMediaButton(prefs.getString("button_single_press_action_selection", "UNKNOWN")); + break; + case 2: + handleMediaButton(prefs.getString("button_double_press_action_selection", "UNKNOWN")); + break; + case 3: + handleMediaButton(prefs.getString("button_triple_press_action_selection", "UNKNOWN")); + break; + default: + break; + } String requiredButtonPressMessage = prefs.getString(HuamiConst.PREF_BUTTON_ACTION_BROADCAST, this.getContext().getString(R.string.mi2_prefs_button_press_broadcast_default_value)); @@ -1111,16 +1142,25 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { in.putExtra("button_id", currentButtonActionId); LOG.info("Sending " + requiredButtonPressMessage + " with button_id " + currentButtonActionId); this.getContext().getApplicationContext().sendBroadcast(in); + if (prefs.getBoolean(HuamiConst.PREF_BUTTON_ACTION_VIBRATE, false)) { vibrateOnce(); } currentButtonActionId = 0; - currentButtonPressCount = 0; currentButtonPressTime = System.currentTimeMillis(); } + private void handleMediaButton(String MediaAction) { + if (MediaAction.equals("UNKNOWN")) { + return; + } + GBDeviceEventMusicControl deviceEventMusicControl = new GBDeviceEventMusicControl(); + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.valueOf(MediaAction); + evaluateGBDeviceEvent(deviceEventMusicControl); + } + private void handleDeviceEvent(byte[] value) { if (value == null || value.length == 0) { return; @@ -1144,12 +1184,16 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { break; case HuamiDeviceEvent.BUTTON_PRESSED_LONG: LOG.info("button long-pressed "); + handleLongButtonEvent(); break; case HuamiDeviceEvent.START_NONWEAR: LOG.info("non-wear start detected"); break; case HuamiDeviceEvent.ALARM_TOGGLED: LOG.info("An alarm was toggled"); + TransactionBuilder builder = new TransactionBuilder("requestAlarms"); + requestAlarms(builder); + builder.queue(getQueue()); break; case HuamiDeviceEvent.FELL_ASLEEP: LOG.info("Fell asleep"); @@ -1212,11 +1256,38 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } evaluateGBDeviceEvent(deviceEventMusicControl); break; + case HuamiDeviceEvent.MTU_REQUEST: + int mtu = (value[2] & 0xff) << 8 | value[1] & 0xff; + LOG.info("device announced MTU of " + mtu); + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress())); + if (!prefs.getBoolean(PREF_ALLOW_HIGH_MTU, false)) { + break; + } + mMTU = mtu; + /* + * not really sure if this would make sense, is this event already a proof of a successful MTU + * negotiation initiated by the Huami device, and acknowledged by the phone? do we really have to + * requestMTU() from our side after receiving this? + * / + if (mMTU != mtu) { + requestMTU(mtu); + } + */ + break; default: LOG.warn("unhandled event " + value[0]); } } + private void requestMTU(int mtu) { + if (GBApplication.isRunningLollipopOrLater()) { + new TransactionBuilder("requestMtu") + .requestMtu(mtu) + .queue(getQueue()); + mMTU = mtu; + } + } + private void acknowledgeFindPhone() { try { TransactionBuilder builder = performInitialized("acknowledge find phone"); @@ -1228,6 +1299,20 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } } + private void handleLongButtonEvent(){ + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress())); + + if (!prefs.getBoolean(HuamiConst.PREF_BUTTON_ACTION_ENABLE, false)) { + return; + } + + currentButtonActionId = 0; + currentButtonPressTime = System.currentTimeMillis(); + currentButtonTimerActivationTime = currentButtonPressTime; + runButtonAction(); + + } + private void handleButtonEvent() { // If disabled we return from function immediately @@ -1237,7 +1322,6 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } int buttonPressMaxDelay = prefs.getInt(HuamiConst.PREF_BUTTON_ACTION_PRESS_MAX_INTERVAL, 2000); - int buttonActionDelay = prefs.getInt(HuamiConst.PREF_BUTTON_ACTION_BROADCAST_DELAY, 0); int requiredButtonPressCount = prefs.getInt(HuamiConst.PREF_BUTTON_ACTION_PRESS_COUNT, 0); if (requiredButtonPressCount > 0) { @@ -1245,36 +1329,34 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { if ((currentButtonPressTime == 0) || (timeSinceLastPress < buttonPressMaxDelay)) { currentButtonPressCount++; - } - else { + } else { currentButtonPressCount = 1; currentButtonActionId = 0; } + if (buttonActionTimer != null){ + buttonActionTimer.cancel(); + } currentButtonPressTime = System.currentTimeMillis(); if (currentButtonPressCount == requiredButtonPressCount) { currentButtonTimerActivationTime = currentButtonPressTime; - if (buttonActionDelay > 0) { - LOG.info("Activating timer"); - final Timer buttonActionTimer = new Timer("Huami Button Action Timer"); - buttonActionTimer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - runButtonAction(); - buttonActionTimer.cancel(); - } - }, buttonActionDelay, buttonActionDelay); - } - else { - LOG.info("Activating button action"); - runButtonAction(); - } + LOG.info("Activating button timer"); + buttonActionTimer = new Timer("Huami Button Action Timer"); + buttonActionTimer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + runButtonAction(); + buttonActionTimer.cancel(); + } + }, buttonPressMaxDelay, buttonPressMaxDelay); + currentButtonActionId++; currentButtonPressCount = 0; } } } + @Override public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { @@ -1300,6 +1382,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } else if (HuamiService.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) { handleRealtimeSteps(characteristic.getValue()); return true; + } else if (HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION.equals(characteristicUUID)) { + handleConfigurationInfo(characteristic.getValue()); + return true; } else { LOG.info("Unhandled characteristic changed: " + characteristicUUID); logMessageContent(characteristic.getValue()); @@ -1394,6 +1479,58 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } } + private void handleConfigurationInfo(byte[] value) { + if (value == null || value.length < 4) { + return; + } + if (value[0] == 0x10 && value[2] == 0x01) { + if (value[1] == 0x0e) { + String gpsVersion = new String(value, 3, value.length - 3); + LOG.info("got gps version = " + gpsVersion); + gbDevice.setFirmwareVersion2(gpsVersion); + } else if (value[1] == 0x0d) { + LOG.info("got alarms from watch"); + decodeAndUpdateAlarmStatus(value); + } else { + LOG.warn("got configuration info we do not handle yet " + GB.hexdump(value, 3, -1)); + } + } else { + LOG.warn("error received from configuration request " + GB.hexdump(value, 0, -1)); + } + } + + private void decodeAndUpdateAlarmStatus(byte[] response) { + List alarms = DBHelper.getAlarms(gbDevice); + int maxAlarms = 10; + boolean[] alarmsInUse = new boolean[maxAlarms]; + boolean[] alarmsEnabled = new boolean[maxAlarms]; + int nr_alarms = response[8]; + for (int i = 0; i < nr_alarms; i++) { + byte alarm_data = response[9 + i]; + int index = alarm_data & 0xf; + if (index >= maxAlarms) { + GB.toast("Unexpected alarm index from device, ignoring: " + index, Toast.LENGTH_SHORT, GB.ERROR); + return; + } + alarmsInUse[index] = true; + boolean enabled = (alarm_data & 0x10) == 0x10; + alarmsEnabled[index] = enabled; + LOG.info("alarm " + index + " is enabled:" + enabled); + } + for (nodomain.freeyourgadget.gadgetbridge.entities.Alarm alarm : alarms) { + boolean enabled = alarmsEnabled[alarm.getPosition()]; + boolean unused = !alarmsInUse[alarm.getPosition()]; + if (alarm.getEnabled() != enabled || alarm.getUnused() != unused) { + LOG.info("updating alarm index " + alarm.getPosition() + " unused=" + unused + ", enabled=" + enabled); + alarm.setEnabled(enabled); + alarm.setUnused(unused); + DBHelper.store(alarm); + Intent intent = new Intent(DeviceService.ACTION_SAVE_ALARMS); + LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent); + } + } + } + private void enableRealtimeSamplesTimer(boolean enable) { if (enable) { getRealtimeSamplesSupport().start(); @@ -1486,17 +1623,25 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { return; } - int base = 0; - if (alarm.getEnabled()) { - base = 128; + int actionMask = 0; + int daysMask = 0; + if (alarm.getEnabled() && !alarm.getUnused()) { + actionMask = 0x80; + + if (coordinator.supportsAlarmSnoozing() && !alarm.getSnooze()) { + actionMask |= 0x40; + } } - int daysMask = alarm.getRepetition(); - if (!alarm.isRepetitive()) { - daysMask = 128; + if (!alarm.getUnused()) { + daysMask = alarm.getRepetition(); + if (!alarm.isRepetitive()) { + daysMask = 128; + } } + byte[] alarmMessage = new byte[] { (byte) 0x2, // TODO what is this? - (byte) (base + alarm.getPosition()), // 128 is the base, alarm slot is added + (byte) (actionMask | alarm.getPosition()), // action mask + alarm slot (byte) calendar.get(Calendar.HOUR_OF_DAY), (byte) calendar.get(Calendar.MINUTE), (byte) daysMask, @@ -1543,7 +1688,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { BluetoothGattCharacteristic characteristic = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION); Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress())); - int availableSlots = prefs.getInt(DeviceSettingsPreferenceConst.PREF_RESERVER_ALARMS_CALENDAR, 0); + int availableSlots = prefs.getInt(PREF_RESERVER_ALARMS_CALENDAR, 0); if (availableSlots > 0) { CalendarEvents upcomingEvents = new CalendarEvents(); @@ -1558,7 +1703,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { int slotToUse = 2 - iteration; Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(mEvt.getBegin()); - Alarm alarm = AlarmUtils.createSingleShot(slotToUse, false, calendar); + Alarm alarm = AlarmUtils.createSingleShot(slotToUse, false, true, calendar); queueAlarm(alarm, builder, characteristic); iteration++; } @@ -1566,6 +1711,60 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { return this; } + private HuamiSupport sendCalendarEventsAsReminder(TransactionBuilder builder) { + boolean syncCalendar = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()).getBoolean(PREF_SYNC_CALENDAR, false); + if (!syncCalendar) { + return this; + } + + CalendarEvents upcomingEvents = new CalendarEvents(); + List calendarEvents = upcomingEvents.getCalendarEventList(getContext()); + Calendar calendar = Calendar.getInstance(); + + int iteration = 0; + + for (CalendarEvents.CalendarEvent calendarEvent : calendarEvents) { + if (iteration > 8) { // limit ? + break; + } + + calendar.setTimeInMillis(calendarEvent.getBegin()); + byte[] title; + byte[] body; + if (calendarEvent.getTitle() != null) { + title = calendarEvent.getTitle().getBytes(); + } else { + title = new byte[]{}; + } + if (calendarEvent.getDescription() != null) { + body = calendarEvent.getDescription().getBytes(); + } else { + body = new byte[]{}; + } + + int length = 18 + title.length + 1 + body.length + 1; + ByteBuffer buf = ByteBuffer.allocate(length); + + buf.order(ByteOrder.LITTLE_ENDIAN); + buf.put((byte) 0x0b); // always 0x0b? + buf.put((byte) iteration); // îd + buf.putInt(0x08 | 0x04 | 0x01); // flags 0x01 = enable, 0x04 = end date present, 0x08 = has text + calendar.setTimeInMillis(calendarEvent.getBegin()); + buf.put(BLETypeConversions.shortCalendarToRawBytes(calendar)); + calendar.setTimeInMillis(calendarEvent.getEnd()); + buf.put(BLETypeConversions.shortCalendarToRawBytes(calendar)); + buf.put(title); + buf.put((byte) 0); // 0 Terminated + buf.put(body); + buf.put((byte) 0); // 0 Terminated + writeToChunked(builder, 2, buf.array()); + + iteration++; + } + + return this; + } + @Override public void onSendConfiguration(String config) { TransactionBuilder builder; @@ -1617,7 +1816,10 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { case MiBandConst.PREF_SWIPE_UNLOCK: setBandScreenUnlock(builder); break; - case DeviceSettingsPreferenceConst.PREF_DATEFORMAT: + case PREF_TIMEFORMAT: + setTimeFormat(builder); + break; + case PREF_DATEFORMAT: setDateFormat(builder); break; case HuamiConst.PREF_LANGUAGE: @@ -1626,7 +1828,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { case HuamiConst.PREF_EXPOSE_HR_THIRDPARTY: setExposeHRThridParty(builder); break; - case DeviceSettingsPreferenceConst.PREF_WEARLOCATION: + case PREF_WEARLOCATION: setWearLocation(builder); break; } @@ -1869,9 +2071,11 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } private HuamiSupport setTimeFormat(TransactionBuilder builder) { - boolean is24Format = DateFormat.is24HourFormat(getContext()); - LOG.info("Setting 24h time format to " + is24Format); - if (is24Format) { + GBPrefs gbPrefs = new GBPrefs(new Prefs(GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()))); + String timeFormat = gbPrefs.getTimeFormat(); + + LOG.info("Setting time format to " + timeFormat); + if (timeFormat.equals("24h")) { builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.DATEFORMAT_TIME_24_HOURS); } else { builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.DATEFORMAT_TIME_12_HOURS); @@ -2170,8 +2374,8 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { return this; } - protected void writeToChunked(TransactionBuilder builder, int type, byte[] data) { - final int MAX_CHUNKLENGTH = 17; + private void writeToChunked(TransactionBuilder builder, int type, byte[] data) { + final int MAX_CHUNKLENGTH = mMTU - 6; int remaining = data.length; byte count = 0; while (remaining > 0) { @@ -2198,6 +2402,19 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } } + + protected HuamiSupport requestGPSVersion(TransactionBuilder builder) { + LOG.info("Requesting GPS version"); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_REQUEST_GPS_VERSION); + return this; + } + + private HuamiSupport requestAlarms(TransactionBuilder builder) { + LOG.info("Requesting alarms"); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_REQUEST_ALARMS); + return this; + } + @Override public String customStringFilter(String inputString) { if (HuamiCoordinator.getUseCustomFont(gbDevice.getAddress())) { @@ -2258,6 +2475,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { setDisconnectNotification(builder); setExposeHRThridParty(builder); setHeartrateMeasurementInterval(builder, getHeartRateMeasurementInterval()); + requestAlarms(builder); } private int getHeartRateMeasurementInterval() { @@ -2271,4 +2489,8 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { public UpdateFirmwareOperation createUpdateFirmwareOperation(Uri uri) { return new UpdateFirmwareOperation(uri, this); } + + public int getMTU() { + return mMTU; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/actions/StopNotificationAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/actions/StopNotificationAction.java index 1077aeedf..8309b4461 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/actions/StopNotificationAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/actions/StopNotificationAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java index e5936c52f..f9ac2c786 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, MyTimeKill +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, MyTimeKill This file is part of Gadgetbridge. @@ -159,9 +159,11 @@ public class AmazfitBipFirmwareInfo extends HuamiFirmwareInfo { // BipOS FW crcToVersion.put(28373, "1.1.2.05 (BipOS 0.5)"); + crcToVersion.put(62977, "1.1.2.05 (BipOS 0.5.1)"); // BipOS RES crcToVersion.put(16303, "1.1.2.05 (BipOS 0.5)"); + crcToVersion.put(61135, "1.1.2.05 (BipOS 0.5.1)"); } public AmazfitBipFirmwareInfo(byte[] bytes) { @@ -171,7 +173,7 @@ public class AmazfitBipFirmwareInfo extends HuamiFirmwareInfo { @Override protected HuamiFirmwareType determineFirmwareType(byte[] bytes) { if (ArrayUtils.startsWith(bytes, RES_HEADER) || ArrayUtils.startsWith(bytes, NEWRES_HEADER)) { - if ((bytes.length <= 100000) || (bytes.length > 700000)) { // dont know how to distinguish from Cor/Mi Band 3 .res + if (bytes.length <= 100000) { // dont know how to distinguish from Cor/Mi Band 3 .res return HuamiFirmwareType.INVALID; } return HuamiFirmwareType.RES; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipLiteFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipLiteFirmwareInfo.java index 6f90a605f..bfe279e8e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipLiteFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipLiteFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipLiteSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipLiteSupport.java index 8d93e29ff..cfda50e50 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipLiteSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipLiteSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java index 1e1b81d15..5b82823cb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, DerFetzer, +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, DerFetzer, Matthieu Baerts, Roi Greenberg This file is part of Gadgetbridge. @@ -17,11 +17,7 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip; -import android.bluetooth.BluetoothGatt; -import android.bluetooth.BluetoothGattCharacteristic; import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; import android.net.Uri; import org.slf4j.Logger; @@ -29,7 +25,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Set; -import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper; @@ -37,21 +32,14 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipFWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; -import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; -import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; -import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory; -import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile; -import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiIcon; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchActivityOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchSportsSummaryOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.HuamiFetchDebugLogsOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy; -import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; public class AmazfitBipSupport extends HuamiSupport { @@ -162,39 +150,6 @@ public class AmazfitBipSupport extends HuamiSupport { } } - @Override - public boolean onCharacteristicChanged(BluetoothGatt gatt, - BluetoothGattCharacteristic characteristic) { - boolean handled = super.onCharacteristicChanged(gatt, characteristic); - if (!handled) { - UUID characteristicUUID = characteristic.getUuid(); - if (HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION.equals(characteristicUUID)) { - return handleConfigurationInfo(characteristic.getValue()); - } - } - return false; - } - - private boolean handleConfigurationInfo(byte[] value) { - if (value == null || value.length < 4) { - return false; - } - if (value[0] == 0x10 && value[1] == 0x0e && value[2] == 0x01) { - String gpsVersion = new String(value, 3, value.length - 3); - LOG.info("got gps version = " + gpsVersion); - gbDevice.setFirmwareVersion2(gpsVersion); - return true; - } - return false; - } - - // this probably does more than only getting the GPS version... - private AmazfitBipSupport requestGPSVersion(TransactionBuilder builder) { - LOG.info("Requesting GPS version"); - builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), AmazfitBipService.COMMAND_REQUEST_GPS_VERSION); - return this; - } - @Override public void phase2Initialize(TransactionBuilder builder) { super.phase2Initialize(builder); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipTextNotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipTextNotificationStrategy.java index e420be9b6..861c408ea 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipTextNotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipTextNotificationStrategy.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorFirmwareInfo.java index f681678c6..270be2906 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. @@ -44,6 +44,7 @@ public class AmazfitCorFirmwareInfo extends HuamiFirmwareInfo { crcToVersion.put(51575, "1.0.7.88"); crcToVersion.put(6346, "1.2.5.00"); crcToVersion.put(24277, "1.2.7.20"); + crcToVersion.put(10078, "1.2.7.32"); // resources crcToVersion.put(46341, "RES 1.0.5.60"); @@ -53,6 +54,7 @@ public class AmazfitCorFirmwareInfo extends HuamiFirmwareInfo { crcToVersion.put(31263, "RES 1.0.7.77-91"); crcToVersion.put(20920, "RES 1.2.5.00-69"); crcToVersion.put(25397, "RES 1.2.7.20"); + crcToVersion.put(54167, "RES 1.2.7.32"); // font crcToVersion.put(61054, "8"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java index 70d2c46cb..cc0729094 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor2/AmazfitCor2FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor2/AmazfitCor2FirmwareInfo.java index 3fcccc536..e1914ea03 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor2/AmazfitCor2FirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor2/AmazfitCor2FirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor2/AmazfitCor2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor2/AmazfitCor2Support.java index ae5b367d9..abc48c5ce 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor2/AmazfitCor2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor2/AmazfitCor2Support.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgtr/AmazfitGTRFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgtr/AmazfitGTRFirmwareInfo.java index e33875519..23cb1d62a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgtr/AmazfitGTRFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgtr/AmazfitGTRFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgtr/AmazfitGTRSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgtr/AmazfitGTRSupport.java index 41144fe87..d73d5cc5e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgtr/AmazfitGTRSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgtr/AmazfitGTRSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts/AmazfitGTSFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts/AmazfitGTSFirmwareInfo.java index f24809de4..9a65c4312 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts/AmazfitGTSFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts/AmazfitGTSFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts/AmazfitGTSSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts/AmazfitGTSSupport.java index 0ce90e425..9d5f0f668 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts/AmazfitGTSSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts/AmazfitGTSSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa, Manuel Ruß +/* Copyright (C) 2019-2020 Andreas Shimokawa, Manuel Ruß This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2FirmwareInfo.java index baa3b924d..1e73e76cb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2FirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2FirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Davis +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Davis Mosenkovs This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2NotificationStrategy.java index 76e1dc365..52b0fad20 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2NotificationStrategy.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Martin Piatka This file is part of Gadgetbridge. @@ -24,6 +24,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory; import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.V2NotificationStrategy; @@ -50,8 +51,11 @@ public class Mi2NotificationStrategy extends V2NotificationStrategy> 8 & 255), (byte) (pause & 255), (byte) (pause >> 8 & 255), repeat}); } - waitDuration = Math.max(waitDuration, 4000); - builder.wait(waitDuration); + // Don't wait during an incoming call, otherwise we'll not be able to stop the call notification + if (simpleNotification == null || simpleNotification.getAlertCategory() != AlertCategory.IncomingCall) { + waitDuration = Math.max(waitDuration, 4000); + builder.wait(waitDuration); + } if (extraAction != null) { builder.add(extraAction); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2TextNotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2TextNotificationStrategy.java index 96291a9bd..e003e5cd7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2TextNotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2TextNotificationStrategy.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java index 4102c7fbd..3cabc1cb9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Davis +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Davis Mosenkovs This file is part of Gadgetbridge. @@ -61,6 +61,7 @@ public class MiBand3FirmwareInfo extends HuamiFirmwareInfo { crcToVersion.put(40949, "2.3.0.28"); crcToVersion.put(59213, "2.4.0.12"); crcToVersion.put(10810, "2.4.0.20"); + crcToVersion.put(18271, "2.4.0.32"); // firmware (Mi Band 3 NFC) crcToVersion.put(46724, "1.7.0.4"); @@ -74,7 +75,7 @@ public class MiBand3FirmwareInfo extends HuamiFirmwareInfo { crcToVersion.put(1815, "2.0.0.4"); crcToVersion.put(7225, "2.2.0.12-2.3.0.6"); crcToVersion.put(52754, "2.3.0.28"); - crcToVersion.put(17930, "2.4.0.12-20"); + crcToVersion.put(17930, "2.4.0.12-32"); // font crcToVersion.put(19775, "1"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3Support.java index a3c99e0e3..ad54a33f1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3Support.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4FirmwareInfo.java index 0a3dd9022..9ce359eae 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4FirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4FirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. @@ -41,12 +41,14 @@ public class MiBand4FirmwareInfo extends HuamiFirmwareInfo { crcToVersion.put(43437, "1.0.5.66"); crcToVersion.put(31632, "1.0.6.00"); crcToVersion.put(6856, "1.0.7.14"); + crcToVersion.put(50145, "1.0.7.60"); // resources crcToVersion.put(27412, "1.0.5.22"); crcToVersion.put(5466, "1.0.5.66"); crcToVersion.put(20047, "1.0.6.00"); crcToVersion.put(62914, "1.0.7.14"); + crcToVersion.put(17303, "1.0.7.60"); // font crcToVersion.put(31978, "1"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4Support.java index 9b101ed87..04bec3ed9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4Support.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/AbstractFetchOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/AbstractFetchOperation.java index 89b2b51bd..d3463c231 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/AbstractFetchOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/AbstractFetchOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, vanous This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchActivityOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchActivityOperation.java index e4f41ab09..6e707f1ff 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchActivityOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchActivityOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java index dddc326e6..89c9cabf6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java index eb2d578a1..d348b665b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/HuamiFetchDebugLogsOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/HuamiFetchDebugLogsOperation.java index 3d4471321..1bc39a391 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/HuamiFetchDebugLogsOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/HuamiFetchDebugLogsOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java index 974b72128..7f56b9267 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. @@ -139,8 +139,8 @@ public class InitOperation extends AbstractBTLEOperation { value[2] == HuamiService.AUTH_SUCCESS) { TransactionBuilder builder = createTransactionBuilder("Authenticated, now initialize phase 2"); builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); - huamiSupport.requestDeviceInfo(builder); huamiSupport.enableFurtherNotifications(builder, true); + huamiSupport.requestDeviceInfo(builder); huamiSupport.phase2Initialize(builder); huamiSupport.phase3Initialize(builder); huamiSupport.setInitialized(builder); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java index 07ca209cd..c62a4bb6b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. @@ -232,7 +232,7 @@ public class UpdateFirmwareOperation extends AbstractHuamiOperation { private boolean sendFirmwareData(HuamiFirmwareInfo info) { byte[] fwbytes = info.getBytes(); int len = fwbytes.length; - final int packetLength = 20; + final int packetLength = getSupport().getMTU() - 3; int packets = len / packetLength; try { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperationNew.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperationNew.java index a13e04348..a8a0a29ae 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperationNew.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperationNew.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa +/* Copyright (C) 2019-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/AbstractID115Operation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/AbstractID115Operation.java index 369234084..f02c73007 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/AbstractID115Operation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/AbstractID115Operation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Vadim Kaushan +/* Copyright (C) 2018-2020 Vadim Kaushan This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/FetchActivityOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/FetchActivityOperation.java index 7f5aa8b50..5edae2ead 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/FetchActivityOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/FetchActivityOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Vadim Kaushan +/* Copyright (C) 2018-2020 Vadim Kaushan This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index bcc2c1206..b2e0d1504 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Andreas Shimokawa, Carsten Pfeiffer, Sebastian +/* Copyright (C) 2018-2020 Andreas Shimokawa, Carsten Pfeiffer, Sebastian Kranz, Vadim Kaushan This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/SendNotificationOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/SendNotificationOperation.java index bbe01da99..a1cdb7c56 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/SendNotificationOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/SendNotificationOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Vadim Kaushan +/* Copyright (C) 2018-2020 Vadim Kaushan This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/itag/ITagSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/itag/ITagSupport.java new file mode 100644 index 000000000..923fbcf48 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/itag/ITagSupport.java @@ -0,0 +1,303 @@ +/* Copyright (C) 2016-2018 Andreas Shimokawa, Carsten Pfeiffer, Taavi Eomäe + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.itag; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.Uri; + +import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; +import nodomain.freeyourgadget.gadgetbridge.devices.itag.ITagConstants; +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.CannedMessagesSpec; +import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; +import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; +import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.IntentListener; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.battery.BatteryInfoProfile; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile; + +public class ITagSupport extends AbstractBTLEDeviceSupport { + + private static final Logger LOG = LoggerFactory.getLogger(ITagSupport.class); + private final GBDeviceEventBatteryInfo batteryCmd = new GBDeviceEventBatteryInfo(); + private final DeviceInfoProfile deviceInfoProfile; + private final BatteryInfoProfile batteryInfoProfile; + + private final IntentListener mListener = new IntentListener() { + @Override + public void notify(Intent intent) { + String s = intent.getAction(); + if (s.equals(DeviceInfoProfile.ACTION_DEVICE_INFO)) { + handleDeviceInfo((nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo) intent.getParcelableExtra(DeviceInfoProfile.EXTRA_DEVICE_INFO)); + } else if (s.equals(BatteryInfoProfile.ACTION_BATTERY_INFO)) { + handleBatteryInfo((nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.battery.BatteryInfo) intent.getParcelableExtra(BatteryInfoProfile.EXTRA_BATTERY_INFO)); + } + } + }; + + public ITagSupport() { + super(LOG); + addSupportedService(GattService.UUID_SERVICE_GENERIC_ACCESS); + addSupportedService(GattService.UUID_SERVICE_GENERIC_ATTRIBUTE); + addSupportedService(GattService.UUID_SERVICE_BATTERY_SERVICE); + + addSupportedService(GattService.UUID_SERVICE_IMMEDIATE_ALERT); + addSupportedService(ITagConstants.UUID_SERVICE_BUTTON); + + + deviceInfoProfile = new DeviceInfoProfile<>(this); + deviceInfoProfile.addListener(mListener); + batteryInfoProfile = new BatteryInfoProfile<>(this); + batteryInfoProfile.addListener(mListener); + + addSupportedProfile(deviceInfoProfile); + addSupportedProfile(batteryInfoProfile); + } + + private void handleBatteryInfo(nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.battery.BatteryInfo info) { + batteryCmd.level = (short) info.getPercentCharged(); + handleGBDeviceEvent(batteryCmd); + } + + @Override + protected TransactionBuilder initializeDevice(TransactionBuilder builder) { + builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); + requestDeviceInfo(builder); + setInitialized(builder); + batteryInfoProfile.requestBatteryInfo(builder); + return builder; + } + + private void requestDeviceInfo(TransactionBuilder builder) { + LOG.debug("Requesting device info!"); + deviceInfoProfile.requestDeviceInfo(builder); + } + + private void setInitialized(TransactionBuilder builder) { + builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZED, getContext())); + } + + + @Override + public boolean useAutoConnect() { + return true; + } + + private void handleDeviceInfo(nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo info) { + + } + + @Override + public void onNotification(NotificationSpec notificationSpec) { + } + + @Override + public void onDeleteNotification(int id) { + + } + + @Override + public void onSetTime() { + + } + + @Override + public void onSetAlarms(ArrayList alarms) { + + } + + @Override + public void onSetCallState(CallSpec callSpec) { + + } + + @Override + public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) { + + } + + @Override + public void onSetMusicState(MusicStateSpec stateSpec) { + + } + + @Override + public void onSetMusicInfo(MusicSpec musicSpec) { + + } + + @Override + public void onEnableRealtimeSteps(boolean enable) { + + } + + @Override + public void onInstallApp(Uri uri) { + + } + + @Override + public void onAppInfoReq() { + + } + + @Override + public void onAppStart(UUID uuid, boolean start) { + + } + + @Override + public void onAppDelete(UUID uuid) { + + } + + @Override + public void onAppConfiguration(UUID appUuid, String config, Integer id) { + + } + + @Override + public void onAppReorder(UUID[] uuids) { + + } + + @Override + public void onFetchRecordedData(int dataTypes) { + + } + + @Override + public void onReset(int flags) { + + } + + @Override + public void onHeartRateTest() { + + } + + @Override + public void onEnableRealtimeHeartRateMeasurement(boolean enable) { + + } + + @Override + public void onFindDevice(boolean start) { + onSetConstantVibration(start ? 0x02 : 0x00); + } + + @Override + public void onSetConstantVibration(int intensity) { + getQueue().clear(); + BluetoothGattCharacteristic characteristic = getCharacteristic(ITagConstants.UUID_LINK_LOSS_ALERT_LEVEL); + + TransactionBuilder builder = new TransactionBuilder("beeping"); + builder.write(characteristic, new byte[]{(byte) intensity}); + builder.queue(getQueue()); + } + + @Override + public void onScreenshotReq() { + + } + + @Override + public void onEnableHeartRateSleepSupport(boolean enable) { + + } + + @Override + public void onSetHeartRateMeasurementInterval(int seconds) { + + } + + @Override + public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) { + + } + + @Override + public void onDeleteCalendarEvent(byte type, long id) { + + } + + + @Override + public boolean onCharacteristicChanged(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic) { + if (super.onCharacteristicChanged(gatt, characteristic)) { + return true; + } + + UUID characteristicUUID = characteristic.getUuid(); + LOG.info("Unhandled characteristic changed: " + characteristicUUID); + return false; + } + + @Override + public boolean onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + if (super.onCharacteristicRead(gatt, characteristic, status)) { + return true; + } + UUID characteristicUUID = characteristic.getUuid(); + + LOG.info("Unhandled characteristic read: " + characteristicUUID); + return false; + } + + @Override + public void onSendConfiguration(String config) { + + } + + @Override + public void onReadConfiguration(String config) { + + } + + @Override + public void onTestNewFunction() { + + } + + @Override + public void onSendWeather(WeatherSpec weatherSpec) { + + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/BFH16DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/BFH16DeviceSupport.java index 923f99412..ad71b6249 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/BFH16DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/BFH16DeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Sophanimus +/* Copyright (C) 2019-2020 Sophanimus This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/JYouDataRecord.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/JYouDataRecord.java new file mode 100644 index 000000000..11cb790be --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/JYouDataRecord.java @@ -0,0 +1,81 @@ +/* Copyright (C) 2017-2020 João Paulo Barraca, Pavel Elagin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.jyou; + +/* + * @author Pavel Elagin <elagin.pasha@gmail.com> + */ + +import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; + +public class JYouDataRecord { + public final static int TYPE_UNKNOWN = 0; + public final static int TYPE_SLEEP = 100; + public final static int TYPE_DAY_SUMMARY = 101; + public final static int TYPE_DAY_SLOT = 102; + public final static int TYPE_REALTIME = 103; + + public int type = TYPE_UNKNOWN; + public int activityKind = ActivityKind.TYPE_UNKNOWN; + + /** + * Time of this record in seconds + */ + public int timestamp; + + /** + * Raw data as sent from the device + */ + public byte[] rawData; + + protected JYouDataRecord(){ + + } + + protected JYouDataRecord(byte[] data, int type){ + this.rawData = data; + this.type = type; + } + + public byte[] getRawData() { + + return rawData; + } + + public class RecordInterval { + /** + * Start time of this interval in seconds + */ + public int timestampFrom; + + /** + * End time of this interval in seconds + */ + public int timestampTo; + + /** + * Type of activity {@link ActivityKind} + */ + public int activityKind; + + RecordInterval(int timestampFrom, int timestampTo, int activityKind) { + this.timestampFrom = timestampFrom; + this.timestampTo = timestampTo; + this.activityKind = activityKind; + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/JYouSupport.java similarity index 71% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30Support.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/JYouSupport.java index 368966e15..bcb447b37 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/JYouSupport.java @@ -1,5 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Sami Alaoui, - Sebastian Kranz +/* Copyright (C) 2017-2020 Andreas Shimokawa, Da Pa, Pavel Elagin, Sami Alaoui This file is part of Gadgetbridge. @@ -23,7 +22,6 @@ import android.net.Uri; import android.widget.Toast; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -50,29 +48,32 @@ import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; -public class TeclastH30Support extends AbstractBTLEDeviceSupport { +public class JYouSupport extends AbstractBTLEDeviceSupport { - private static final Logger LOG = LoggerFactory.getLogger(TeclastH30Support.class); + private Logger logger; - public BluetoothGattCharacteristic ctrlCharacteristic = null; - public BluetoothGattCharacteristic measureCharacteristic = null; + protected BluetoothGattCharacteristic ctrlCharacteristic = null; - private final GBDeviceEventVersionInfo versionCmd = new GBDeviceEventVersionInfo(); - private final GBDeviceEventBatteryInfo batteryCmd = new GBDeviceEventBatteryInfo(); + protected final GBDeviceEventVersionInfo versionCmd = new GBDeviceEventVersionInfo(); + protected final GBDeviceEventBatteryInfo batteryCmd = new GBDeviceEventBatteryInfo(); - public TeclastH30Support() { - super(LOG); + public JYouSupport(Logger logger) { + super(logger); + this.logger = logger; + if (logger == null) { + throw new IllegalArgumentException("logger must not be null"); + } addSupportedService(JYouConstants.UUID_SERVICE_JYOU); } @Override protected TransactionBuilder initializeDevice(TransactionBuilder builder) { - LOG.info("Initializing"); + logger.info("Initializing"); gbDevice.setState(GBDevice.State.INITIALIZING); gbDevice.sendDeviceUpdateIntent(getContext()); - measureCharacteristic = getCharacteristic(JYouConstants.UUID_CHARACTERISTIC_MEASURE); + BluetoothGattCharacteristic measureCharacteristic = getCharacteristic(JYouConstants.UUID_CHARACTERISTIC_MEASURE); ctrlCharacteristic = getCharacteristic(JYouConstants.UUID_CHARACTERISTIC_CONTROL); builder.setGattCallback(this); @@ -83,7 +84,7 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { gbDevice.setState(GBDevice.State.INITIALIZED); gbDevice.sendDeviceUpdateIntent(getContext()); - LOG.info("Initialization Done"); + logger.info("Initialization Done"); return builder; } @@ -91,41 +92,10 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { @Override public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { - if (super.onCharacteristicChanged(gatt, characteristic)) { - return true; - } - - UUID characteristicUUID = characteristic.getUuid(); - byte[] data = characteristic.getValue(); - if (data.length == 0) - return true; - - switch (data[0]) { - case JYouConstants.RECEIVE_DEVICE_INFO: - int fwVerNum = data[4] & 0xFF; - versionCmd.fwVersion = (fwVerNum / 100) + "." + ((fwVerNum % 100) / 10) + "." + ((fwVerNum % 100) % 10); - handleGBDeviceEvent(versionCmd); - LOG.info("Firmware version is: " + versionCmd.fwVersion); - return true; - case JYouConstants.RECEIVE_BATTERY_LEVEL: - batteryCmd.level = data[8]; - handleGBDeviceEvent(batteryCmd); - LOG.info("Battery level is: " + batteryCmd.level); - return true; - case JYouConstants.RECEIVE_STEPS_DATA: - int steps = ByteBuffer.wrap(data, 5, 4).getInt(); - LOG.info("Number of walked steps: " + steps); - return true; - case JYouConstants.RECEIVE_HEARTRATE: - LOG.info("Current heart rate: " + data[8]); - return true; - default: - LOG.info("Unhandled characteristic change: " + characteristicUUID + " code: " + String.format("0x%1x ...", data[0])); - return true; - } + return super.onCharacteristicChanged(gatt, characteristic); } - private void syncDateAndTime(TransactionBuilder builder) { + protected void syncDateAndTime(TransactionBuilder builder) { Calendar cal = Calendar.getInstance(); String strYear = String.valueOf(cal.get(Calendar.YEAR)); byte year1 = (byte)Integer.parseInt(strYear.substring(0, 2)); @@ -144,45 +114,7 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { )); } - private void syncSettings(TransactionBuilder builder) { - syncDateAndTime(builder); - - // TODO: unhardcode and separate stuff - builder.write(ctrlCharacteristic, commandWithChecksum( - JYouConstants.CMD_SET_HEARTRATE_WARNING_VALUE, 0, 152 - )); - builder.write(ctrlCharacteristic, commandWithChecksum( - JYouConstants.CMD_SET_TARGET_STEPS, 0, 10000 - )); - builder.write(ctrlCharacteristic, commandWithChecksum( - JYouConstants.CMD_GET_STEP_COUNT, 0, 0 - )); - builder.write(ctrlCharacteristic, commandWithChecksum( - JYouConstants.CMD_GET_SLEEP_TIME, 0, 0 - )); - builder.write(ctrlCharacteristic, commandWithChecksum( - JYouConstants.CMD_SET_NOON_TIME, 12 * 60 * 60, 14 * 60 * 60 // 12:00 - 14:00 - )); - builder.write(ctrlCharacteristic, commandWithChecksum( - JYouConstants.CMD_SET_SLEEP_TIME, 21 * 60 * 60, 8 * 60 * 60 // 21:00 - 08:00 - )); - builder.write(ctrlCharacteristic, commandWithChecksum( - JYouConstants.CMD_SET_INACTIVITY_WARNING_TIME, 0, 0 - )); - - // do not disturb and a couple more features - byte dndStartHour = 22; - byte dndStartMin = 0; - byte dndEndHour = 8; - byte dndEndMin = 0; - boolean dndToggle = false; - boolean vibrationToggle = true; - boolean wakeOnRaiseToggle = true; - builder.write(ctrlCharacteristic, commandWithChecksum( - JYouConstants.CMD_SET_DND_SETTINGS, - (dndStartHour << 24) | (dndStartMin << 16) | (dndEndHour << 8) | dndEndMin, - ((dndToggle ? 0 : 1) << 2) | ((vibrationToggle ? 1 : 0) << 1) | (wakeOnRaiseToggle ? 1 : 0) - )); + protected void syncSettings(TransactionBuilder builder) { } private void showNotification(byte icon, String title, String message) { @@ -217,9 +149,9 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { } builder.write(ctrlCharacteristic, currentPacket); } - builder.queue(getQueue()); + performConnected(builder.getTransaction()); } catch (IOException e) { - LOG.warn(e.getMessage()); + logger.warn(e.getMessage()); } } @@ -286,10 +218,10 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { alarms.get(i).getEnabled() ? cal.get(Calendar.MINUTE) : -1 )); } - builder.queue(getQueue()); + performConnected(builder.getTransaction()); GB.toast(getContext(), "Alarm settings applied - do note that the current device does not support day specification", Toast.LENGTH_LONG, GB.INFO); } catch(IOException e) { - LOG.warn(e.getMessage()); + logger.warn(e.getMessage()); } } @@ -298,18 +230,16 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { try { TransactionBuilder builder = performInitialized("SetTime"); syncDateAndTime(builder); - builder.queue(getQueue()); + performConnected(builder.getTransaction()); } catch(IOException e) { - LOG.warn(e.getMessage()); + logger.warn(e.getMessage()); } } @Override public void onSetCallState(CallSpec callSpec) { - switch (callSpec.command) { - case CallSpec.CALL_INCOMING: - showNotification(JYouConstants.ICON_CALL, callSpec.name, callSpec.number); - break; + if(callSpec.command == CallSpec.CALL_INCOMING) { + showNotification(JYouConstants.ICON_CALL, callSpec.name, callSpec.number); } } @@ -375,9 +305,9 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { builder.write(ctrlCharacteristic, commandWithChecksum( JYouConstants.CMD_ACTION_REBOOT_DEVICE, 0, 0 )); - builder.queue(getQueue()); + performConnected(builder.getTransaction()); } catch(Exception e) { - LOG.warn(e.getMessage()); + logger.warn(e.getMessage()); } } @@ -388,15 +318,14 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { builder.write(ctrlCharacteristic, commandWithChecksum( JYouConstants.CMD_ACTION_HEARTRATE_SWITCH, 0, 1 )); - builder.queue(getQueue()); + performConnected(builder.getTransaction()); } catch(Exception e) { - LOG.warn(e.getMessage()); + logger.warn(e.getMessage()); } } @Override public void onEnableRealtimeHeartRateMeasurement(boolean enable) { - // TODO: test try { TransactionBuilder builder = performInitialized("RealTimeHeartMeasurement"); builder.write(ctrlCharacteristic, commandWithChecksum( @@ -404,7 +333,7 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { )); builder.queue(getQueue()); } catch(Exception e) { - LOG.warn(e.getMessage()); + logger.warn(e.getMessage()); } } @@ -466,7 +395,7 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { } - private byte[] commandWithChecksum(byte cmd, int argSlot1, int argSlot2) + protected byte[] commandWithChecksum(byte cmd, int argSlot1, int argSlot2) { ByteBuffer buf = ByteBuffer.allocate(10); buf.put(cmd); @@ -505,7 +434,7 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { } } } catch (UnsupportedEncodingException e) { - LOG.warn(e.getMessage()); + logger.warn(e.getMessage()); } return null; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/RealtimeSamplesSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/RealtimeSamplesSupport.java new file mode 100644 index 000000000..287d6be66 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/RealtimeSamplesSupport.java @@ -0,0 +1,111 @@ +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Pavel Elagin + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.jyou; + +import java.util.Timer; +import java.util.TimerTask; + +import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; + +public abstract class RealtimeSamplesSupport { + private final long delay; + private final long period; + + protected int steps; + protected int heartrateBpm; + private int lastSteps; + // subclasses may add more + + private Timer realtimeStorageTimer; + + public RealtimeSamplesSupport(long delay, long period) { + this.delay = delay; + this.period = period; + } + + public synchronized void start() { + if (isRunning()) { + return; // already running + } + realtimeStorageTimer = new Timer("JYou Realtime Storage Timer"); + realtimeStorageTimer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + triggerCurrentSample(); + } + }, delay, period); + } + + public synchronized void stop() { + if (realtimeStorageTimer != null) { + realtimeStorageTimer.cancel(); + realtimeStorageTimer.purge(); + realtimeStorageTimer = null; + } + } + + public synchronized boolean isRunning() { + return realtimeStorageTimer != null; + } + + public synchronized void setSteps(int stepsPerMinute) { + this.steps = stepsPerMinute; + } + + /** + * Returns the number of steps recorded since the last measurements. If no + * steps are available yet, ActivitySample.NOT_MEASURED is returned. + * @return + */ + public synchronized int getSteps() { + if (steps == ActivitySample.NOT_MEASURED) { + return ActivitySample.NOT_MEASURED; + } + if (lastSteps == 0) { + return ActivitySample.NOT_MEASURED; // wait until we have a delta between two samples + } + int delta = steps - lastSteps; + if (delta < 0) { + return 0; + } + return delta; + } + + public void setHeartrateBpm(int hrBpm) { + this.heartrateBpm = hrBpm; + } + + public int getHeartrateBpm() { + return heartrateBpm; + } + + public void triggerCurrentSample() { + doCurrentSample(); + resetCurrentValues(); + } + + protected synchronized void resetCurrentValues() { + if (steps >= lastSteps) { + lastSteps = steps; + } + steps = ActivitySample.NOT_MEASURED; + heartrateBpm = ActivitySample.NOT_MEASURED; + } + + protected abstract void doCurrentSample(); +} + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30/TeclastH30Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30/TeclastH30Support.java new file mode 100644 index 000000000..1950c8fc4 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30/TeclastH30Support.java @@ -0,0 +1,120 @@ +/* Copyright (C) 2017-2020 Andreas Shimokawa, Da Pa, Pavel Elagin, Sami Alaoui + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.jyou.TeclastH30; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.ByteBuffer; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.devices.jyou.JYouConstants; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.jyou.JYouSupport; + +public class TeclastH30Support extends JYouSupport { + + private static final Logger LOG = LoggerFactory.getLogger(TeclastH30Support.class); + + public TeclastH30Support() { + super(LOG); + addSupportedService(JYouConstants.UUID_SERVICE_JYOU); + } + + @Override + public boolean onCharacteristicChanged(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic) { + if (super.onCharacteristicChanged(gatt, characteristic)) { + return true; + } + + UUID characteristicUUID = characteristic.getUuid(); + byte[] data = characteristic.getValue(); + if (data.length == 0) + return true; + + switch (data[0]) { + case JYouConstants.RECEIVE_DEVICE_INFO: + int fwVerNum = data[4] & 0xFF; + versionCmd.fwVersion = (fwVerNum / 100) + "." + ((fwVerNum % 100) / 10) + "." + ((fwVerNum % 100) % 10); + handleGBDeviceEvent(versionCmd); + LOG.info("Firmware version is: " + versionCmd.fwVersion); + return true; + case JYouConstants.RECEIVE_BATTERY_LEVEL: + batteryCmd.level = data[8]; + handleGBDeviceEvent(batteryCmd); + LOG.info("Battery level is: " + batteryCmd.level); + return true; + case JYouConstants.RECEIVE_STEPS_DATA: + int steps = ByteBuffer.wrap(data, 5, 4).getInt(); + LOG.info("Number of walked steps: " + steps); + return true; + case JYouConstants.RECEIVE_HEARTRATE: + LOG.info("Current heart rate: " + data[8]); + return true; + default: + LOG.info("Unhandled characteristic change: " + characteristicUUID + " code: " + String.format("0x%1x ...", data[0])); + return true; + } + } + + @Override + protected void syncSettings(TransactionBuilder builder) { + syncDateAndTime(builder); + + // TODO: unhardcode and separate stuff + builder.write(ctrlCharacteristic, commandWithChecksum( + JYouConstants.CMD_SET_HEARTRATE_WARNING_VALUE, 0, 152 + )); + builder.write(ctrlCharacteristic, commandWithChecksum( + JYouConstants.CMD_SET_TARGET_STEPS, 0, 10000 + )); + builder.write(ctrlCharacteristic, commandWithChecksum( + JYouConstants.CMD_GET_STEP_COUNT, 0, 0 + )); + builder.write(ctrlCharacteristic, commandWithChecksum( + JYouConstants.CMD_GET_SLEEP_TIME, 0, 0 + )); + builder.write(ctrlCharacteristic, commandWithChecksum( + JYouConstants.CMD_SET_NOON_TIME, 12 * 60 * 60, 14 * 60 * 60 // 12:00 - 14:00 + )); + builder.write(ctrlCharacteristic, commandWithChecksum( + JYouConstants.CMD_SET_SLEEP_TIME, 21 * 60 * 60, 8 * 60 * 60 // 21:00 - 08:00 + )); + builder.write(ctrlCharacteristic, commandWithChecksum( + JYouConstants.CMD_SET_INACTIVITY_WARNING_TIME, 0, 0 + )); + + // do not disturb and a couple more features + byte dndStartHour = 22; + byte dndStartMin = 0; + byte dndEndHour = 8; + byte dndEndMin = 0; + boolean dndToggle = false; + boolean vibrationToggle = true; + boolean wakeOnRaiseToggle = true; + builder.write(ctrlCharacteristic, commandWithChecksum( + JYouConstants.CMD_SET_DND_SETTINGS, + (dndStartHour << 24) | (dndStartMin << 16) | (dndEndHour << 8) | dndEndMin, + ((dndToggle ? 0 : 1) << 2) | ((vibrationToggle ? 1 : 0) << 1) | (wakeOnRaiseToggle ? 1 : 0) + )); + } + +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/y5/Y5Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/y5/Y5Support.java new file mode 100644 index 000000000..d09b6f2e1 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/y5/Y5Support.java @@ -0,0 +1,232 @@ +/* Copyright (C) 2017-2020 Andreas Shimokawa, Da Pa, Pavel Elagin, Sami Alaoui + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.jyou.y5; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.content.Intent; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.ByteBuffer; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; +import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.devices.jyou.JYouConstants; +import nodomain.freeyourgadget.gadgetbridge.devices.jyou.JYouSampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; +import nodomain.freeyourgadget.gadgetbridge.entities.Device; +import nodomain.freeyourgadget.gadgetbridge.entities.JYouActivitySample; +import nodomain.freeyourgadget.gadgetbridge.entities.User; +import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.jyou.JYouSupport; +import nodomain.freeyourgadget.gadgetbridge.service.devices.jyou.RealtimeSamplesSupport; + +public class Y5Support extends JYouSupport { + private static final Logger LOG = LoggerFactory.getLogger(Y5Support.class); + + private RealtimeSamplesSupport realtimeSamplesSupport; + + + public Y5Support() { + super(LOG); + addSupportedService(JYouConstants.UUID_SERVICE_JYOU); + } + + @Override + public boolean onCharacteristicChanged(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic) { + if (super.onCharacteristicChanged(gatt, characteristic)) { + return true; + } + + UUID characteristicUUID = characteristic.getUuid(); + byte[] data = characteristic.getValue(); + if (data.length == 0) + return true; + + switch (data[0]) { + case JYouConstants.RECEIVE_HISTORY_SLEEP_COUNT: + LOG.info("onCharacteristicChanged: " + data[0]); + return true; + case JYouConstants.RECEIVE_BLOOD_PRESSURE: + int heartRate = data[2]; + int bloodPressureHigh = data[3]; + int bloodPressureLow = data[4]; + int bloodOxygen = data[5]; + int Fatigue = data[6]; + LOG.info("RECEIVE_BLOOD_PRESSURE: Heart rate: " + heartRate + " Pressure high: " + bloodPressureHigh+ " pressure low: " + bloodPressureLow); + return true; + case JYouConstants.RECEIVE_DEVICE_INFO: + int model = data[7]; + int fwVerNum = data[4] & 0xFF; + versionCmd.fwVersion = (fwVerNum / 100) + "." + ((fwVerNum % 100) / 10) + "." + ((fwVerNum % 100) % 10); + handleGBDeviceEvent(versionCmd); + LOG.info("Firmware version is: " + versionCmd.fwVersion); + return true; + case JYouConstants.RECEIVE_BATTERY_LEVEL: + batteryCmd.level = data[8]; + handleGBDeviceEvent(batteryCmd); + LOG.info("Battery level is: " + batteryCmd.level); + return true; + case JYouConstants.RECEIVE_STEPS_DATA: + int steps = ByteBuffer.wrap(data, 5, 4).getInt(); + LOG.info("Number of walked steps: " + steps); + handleRealtimeSteps(steps); + return true; + case JYouConstants.RECEIVE_HEARTRATE: + handleHeartrate(data[8]); + return true; + case JYouConstants.RECEIVE_WATCH_MAC: + return true; + case JYouConstants.RECEIVE_GET_PHOTO: + return true; + default: + LOG.info("Unhandled characteristic change: " + characteristicUUID + " code: " + String.format("0x%1x ...", data[0])); + return true; + } + } + + private void handleRealtimeSteps(int value) { + //todo Call on connect the device + if (LOG.isDebugEnabled()) { + LOG.debug("realtime steps: " + value); + } + getRealtimeSamplesSupport().setSteps(value); + } + + private void handleHeartrate(int value) { + if (LOG.isDebugEnabled()) { + LOG.debug("heart rate: " + value); + } + RealtimeSamplesSupport realtimeSamplesSupport = getRealtimeSamplesSupport(); + realtimeSamplesSupport.setHeartrateBpm(value); + if (!realtimeSamplesSupport.isRunning()) { + // single shot measurement, manually invoke storage and result publishing + realtimeSamplesSupport.triggerCurrentSample(); + } + } + + public JYouActivitySample createActivitySample(Device device, User user, int timestampInSeconds, SampleProvider provider) { + JYouActivitySample sample = new JYouActivitySample(); + sample.setDevice(device); + sample.setUser(user); + sample.setTimestamp(timestampInSeconds); + sample.setProvider(provider); + return sample; + } + + private void enableRealtimeSamplesTimer(boolean enable) { + if (enable) { + getRealtimeSamplesSupport().start(); + } else { + if (realtimeSamplesSupport != null) { + realtimeSamplesSupport.stop(); + } + } + } + + private RealtimeSamplesSupport getRealtimeSamplesSupport() { + if (realtimeSamplesSupport == null) { + realtimeSamplesSupport = new RealtimeSamplesSupport(1000, 1000) { + @Override + public void doCurrentSample() { + + try (DBHandler handler = GBApplication.acquireDB()) { + DaoSession session = handler.getDaoSession(); + int ts = (int) (System.currentTimeMillis() / 1000); + JYouSampleProvider provider = new JYouSampleProvider(gbDevice, session); + JYouActivitySample sample = createActivitySample(DBHelper.getDevice(getDevice(), session), DBHelper.getUser(session), ts, provider); + sample.setHeartRate(getHeartrateBpm()); + sample.setRawIntensity(ActivitySample.NOT_MEASURED); + sample.setRawKind(JYouSampleProvider.TYPE_ACTIVITY); // to make it visible in the charts TODO: add a MANUAL kind for that? + + provider.addGBActivitySample(sample); + + // set the steps only afterwards, since realtime steps are also recorded + // in the regular samples and we must not count them twice + // Note: we know that the DAO sample is never committed again, so we simply + // change the value here in memory. + sample.setSteps(getSteps()); + if(steps > 1){ + LOG.debug("Have steps: " + getSteps()); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("realtime sample: " + sample); + } + + Intent intent = new Intent(DeviceService.ACTION_REALTIME_SAMPLES) + .putExtra(DeviceService.EXTRA_REALTIME_SAMPLE, sample); + LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent); + + } catch (Exception e) { + LOG.warn("Unable to acquire db for saving realtime samples", e); + } + } + }; + } + return realtimeSamplesSupport; + } + + @Override + protected void syncSettings(TransactionBuilder builder) { + syncDateAndTime(builder); + } + + @Override + public void dispose() { + LOG.info("Dispose"); + super.dispose(); + } + + @Override + public void onHeartRateTest() { + try { + TransactionBuilder builder = performInitialized("HeartRateTest"); + builder.write(ctrlCharacteristic, commandWithChecksum( + JYouConstants.CMD_SET_HEARTRATE_AUTO, 0, 0 + + )); + performConnected(builder.getTransaction()); + } catch(Exception e) { + LOG.warn(e.getMessage()); + } + } + + @Override + public void onEnableRealtimeHeartRateMeasurement(boolean enable) { + try { + TransactionBuilder builder = performInitialized("RealTimeHeartMeasurement"); + builder.write(ctrlCharacteristic, commandWithChecksum( + JYouConstants.CMD_ACTION_HEARTRATE_SWITCH, 0, enable ? 1 : 0 + )); + performConnected(builder.getTransaction()); + enableRealtimeSamplesTimer(enable); + } catch (Exception e) { + LOG.warn(e.getMessage()); + } + } + +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewIoThread.java index d35619400..54b61b542 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewIoThread.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewProtocol.java index c9f8a4175..29ea5d64d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewProtocol.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Daniele Gobbetti +/* Copyright (C) 2016-2020 Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java index c772be99d..7eb48111a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Daniele Gobbetti, Sebastian +/* Copyright (C) 2016-2020 Andreas Shimokawa, Daniele Gobbetti, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/makibeshr3/MakibesHR3DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/makibeshr3/MakibesHR3DeviceSupport.java index f3395e406..fe024955d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/makibeshr3/MakibesHR3DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/makibeshr3/MakibesHR3DeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa, Cre3per +/* Copyright (C) 2019-2020 Andreas Shimokawa, Cre3per This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractInfo.java index 0703ff15f..5e91f602b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer +/* Copyright (C) 2015-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMi1FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMi1FirmwareInfo.java index 334dec391..e07da5b2c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMi1FirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMi1FirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMi1SFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMi1SFirmwareInfo.java index 7bf1c02ba..0f7d647aa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMi1SFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMi1SFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMiFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMiFirmwareInfo.java index deaaed0d4..84427e5d7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMiFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/AbstractMiFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java index 66910462e..2eddc455d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/CheckAuthenticationNeededAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/CheckAuthenticationNeededAction.java index bcec4f661..8fb11d7f9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/CheckAuthenticationNeededAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/CheckAuthenticationNeededAction.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/CompositeMiFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/CompositeMiFirmwareInfo.java index 0080ec819..b11c6517d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/CompositeMiFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/CompositeMiFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/DeviceInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/DeviceInfo.java index 1fabf841e..4d03749fe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/DeviceInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/DeviceInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Sergey Trofimov This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1AFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1AFirmwareInfo.java index d9f3539b4..f2b7fe41e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1AFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1AFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1FirmwareInfo.java index 0a0a91928..d467dd1d4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1FirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1FirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfo.java index e0fb2b498..eb91d633c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfoFW1.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfoFW1.java index c623caf88..aaf093662 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfoFW1.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfoFW1.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfoFW2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfoFW2.java index 3a6fd067a..dae76a1c2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfoFW2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/Mi1SFirmwareInfoFW2.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java index d6eb3b299..1ac09ec40 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, atkyritsis, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 Andreas Shimokawa, atkyritsis, Carsten Pfeiffer, Christian Fischer, Daniele Gobbetti, freezed-or-frozen, JohnnySun, Julien Pivotto, Kasha, Sebastian Kranz, Sergey Trofimov, Steffen Liebergeld @@ -1243,7 +1243,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { int slotToUse = 2 - iteration; Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(mEvt.getBegin()); - Alarm alarm = AlarmUtils.createSingleShot(slotToUse, false, calendar); + Alarm alarm = AlarmUtils.createSingleShot(slotToUse, false, false, calendar); queueAlarm(alarm, builder, characteristic); iteration++; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java index 0fbe52ee3..8308ad605 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2015-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java index e5a58483b..f93a3a6fd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2015-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/RealtimeSamplesSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/RealtimeSamplesSupport.java index 19763ebbf..685191c74 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/RealtimeSamplesSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/RealtimeSamplesSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/TestMi1AFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/TestMi1AFirmwareInfo.java index d95110e72..6d0eca121 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/TestMi1AFirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/TestMi1AFirmwareInfo.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java index 407338138..73fccc0cb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer +/* Copyright (C) 2015-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java index 39923a9de..7b8478e9f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2015-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBand1Operation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBand1Operation.java index 951947c9f..4e0028c80 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBand1Operation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBand1Operation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBandOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBandOperation.java index b38f0b340..db483d994 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBandOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBandOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java index e63aa6467..a841e6896 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/OperationStatus.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/OperationStatus.java index df634cfae..b0e9e0602 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/OperationStatus.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/OperationStatus.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer +/* Copyright (C) 2016-2020 Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/UpdateFirmwareOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/UpdateFirmwareOperation.java index 05f99a398..9e27f34fd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/UpdateFirmwareOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/UpdateFirmwareOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/mijia_lywsd02/MijiaLywsd02Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/mijia_lywsd02/MijiaLywsd02Support.java index c40a1e16b..ed1ded857 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/mijia_lywsd02/MijiaLywsd02Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/mijia_lywsd02/MijiaLywsd02Support.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Sebastian +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miscale2/MiScale2DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miscale2/MiScale2DeviceSupport.java index 83b009e0d..0f16bbcdf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miscale2/MiScale2DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miscale2/MiScale2DeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Jean-François +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Jean-François Greffier This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java index 1d65fe7a1..9484a28ef 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin, protomors, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandler.java index 5e0978686..57625466a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandler.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerGBPebble.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerGBPebble.java index 9022af4e9..ade28474e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerGBPebble.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerGBPebble.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerHealthify.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerHealthify.java index 42c29a6da..3a972c12b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerHealthify.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerHealthify.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerM7S.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerM7S.java index 5bd37ae34..c195608f5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerM7S.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerM7S.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Carsten Pfeiffer, jcrode, Johann C. Rode, +/* Copyright (C) 2018-2020 Carsten Pfeiffer, jcrode, Johann C. Rode, Sergio Lopez This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMarioTime.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMarioTime.java index fe9c1b678..59203ac86 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMarioTime.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMarioTime.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMisfit.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMisfit.java index 165c9059d..f0e1e6c25 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMisfit.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMisfit.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMorpheuz.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMorpheuz.java index e0625712a..53440eb99 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMorpheuz.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerMorpheuz.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerObsidian.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerObsidian.java index 2cfc6178d..2c1005bb5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerObsidian.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerObsidian.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Daniele Gobbetti, Johann C. Rode +/* Copyright (C) 2015-2020 Andreas Shimokawa, Daniele Gobbetti, Johann C. Rode This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerPebStyle.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerPebStyle.java index 853ed062e..a599dbcc6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerPebStyle.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerPebStyle.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Daniele Gobbetti, Uwe Hermann +/* Copyright (C) 2015-2020 Andreas Shimokawa, Daniele Gobbetti, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerRealWeather.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerRealWeather.java index 365c756ba..93834ccff 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerRealWeather.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerRealWeather.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Carsten Pfeiffer, Johann C. Rode, Sergio Lopez +/* Copyright (C) 2018-2020 Carsten Pfeiffer, Johann C. Rode, Sergio Lopez This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerSimplyLight.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerSimplyLight.java index 7b8c89a43..364613de6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerSimplyLight.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerSimplyLight.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Carsten Pfeiffer, Sergio Lopez +/* Copyright (C) 2018-2020 Carsten Pfeiffer, Sergio Lopez This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerSquare.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerSquare.java index fd9b2b8e3..d84f04cd9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerSquare.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerSquare.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2016-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTimeStylePebble.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTimeStylePebble.java index 898b77f01..4c315ce60 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTimeStylePebble.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTimeStylePebble.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2015-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTrekVolle.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTrekVolle.java index 652724013..9b9bbb24a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTrekVolle.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTrekVolle.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa +/* Copyright (C) 2017-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerYWeather.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerYWeather.java index 297e4830f..6ac3a5cc7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerYWeather.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerYWeather.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Carsten Pfeiffer, Johann C. Rode +/* Copyright (C) 2018-2020 Carsten Pfeiffer, Johann C. Rode This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerZalewszczak.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerZalewszczak.java index 9d046be7b..7b648edd3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerZalewszczak.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerZalewszczak.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSession.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSession.java index 2adb41f2a..3b3469a1c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSession.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSession.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionAnalytics.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionAnalytics.java index 59b2c8689..5d885dba7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionAnalytics.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionAnalytics.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthHR.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthHR.java index d03d15f22..435363d22 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthHR.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthHR.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java index f6c98a42f..668a02f70 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java index 1c61b70b9..6b68a833c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2016-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java index ee0843a92..c112be3e9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2016-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionPebbleHealth.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionPebbleHealth.java index 40126af2e..f851abc67 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionPebbleHealth.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionPebbleHealth.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleActiveAppTracker.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleActiveAppTracker.java index fc7c30e69..5181e3d4c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleActiveAppTracker.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleActiveAppTracker.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Matej Drobnič +/* Copyright (C) 2019-2020 Matej Drobnič This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java index e137d2337..f52a3292a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Julien Pivotto, Matej Drobnič, Uwe Hermann This file is part of Gadgetbridge. @@ -467,7 +467,7 @@ class PebbleIoThread extends GBDeviceIoThread { write_real(bytes); } - // FIXME: parts are supporsed to be generic code + // FIXME: parts are supposed to be generic code private boolean evaluateGBDeviceEventPebble(GBDeviceEvent deviceEvent) { if (deviceEvent instanceof GBDeviceEventVersionInfo) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleKitSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleKitSupport.java index bb2ebd326..3066175fa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleKitSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleKitSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Matej Drobnič +/* Copyright (C) 2017-2020 Andreas Shimokawa, Matej Drobnič This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index 40b702071..17c483e69 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Frank Slezak, jcrode, Johann C. Rode, Julien Pivotto, Kevin Richter, Matej Drobnič, Sergio Lopez, Steffen Liebergeld, Uwe Hermann diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java index 707d60063..32a31dc60 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Kasha, Sebastian Kranz, Steffen Liebergeld This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTClient.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTClient.java index c8b5eeaf1..6f318bcc8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTClient.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTClient.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa +/* Copyright (C) 2016-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTServer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTServer.java index da7696162..e7c4bbcce 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTServer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleGATTServer.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Daniele Gobbetti, Uwe Hermann +/* Copyright (C) 2016-2020 Andreas Shimokawa, Daniele Gobbetti, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java index e81550639..af228bfaf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2016-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/CurrentPosition.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/CurrentPosition.java index 654021da3..6a0499e32 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/CurrentPosition.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/CurrentPosition.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Daniele Gobbetti +/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/GBChromeClient.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/GBChromeClient.java index f7b8bd158..a958d3946 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/GBChromeClient.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/GBChromeClient.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Daniele Gobbetti +/* Copyright (C) 2017-2020 Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/GBWebClient.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/GBWebClient.java index bda815a2f..c85d67eaf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/GBWebClient.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/GBWebClient.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/JSInterface.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/JSInterface.java index 23ba998a9..99fd5dc0f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/JSInterface.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/JSInterface.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridBaseSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridBaseSupport.java index 3e51149b3..6ab294777 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridBaseSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridBaseSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniel +/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, José Rebelo, Julien Pivotto, Sebastian Kranz, Steffen Liebergeld This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java index 27fc36c8a..f30191093 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -29,9 +29,10 @@ import android.media.AudioManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.util.Log; import android.widget.Toast; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,35 +42,37 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.UUID; -import androidx.annotation.RequiresApi; -import androidx.localbroadcastmanager.content.LocalBroadcastManager; - +import nodomain.freeyourgadget.gadgetbridge.BuildConfig; import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper; -import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster; -import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.externalevents.NotificationListener; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; +import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.GenericItem; +import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; +import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes; -import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCallback; +import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapterFactory; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.DownloadFileRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest; +import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; public class QHybridSupport extends QHybridBaseSupport { @@ -82,6 +85,10 @@ public class QHybridSupport extends QHybridBaseSupport { public static final String QHYBRID_COMMAND_NOTIFICATION = "qhybrid_command_notification"; public static final String QHYBRID_COMMAND_UPDATE_SETTINGS = "nodomain.freeyourgadget.gadgetbridge.Q_UPDATE_SETTINGS"; public static final String QHYBRID_COMMAND_OVERWRITE_BUTTONS = "nodomain.freeyourgadget.gadgetbridge.Q_OVERWRITE_BUTTONS"; + public static final String QHYBRID_COMMAND_UPDATE_WIDGETS = "nodomain.freeyourgadget.gadgetbridge.Q_UPDATE_WIDGETS"; + public static final String QHYBRID_COMMAND_SET_MENU_MESSAGE = "nodomain.freeyourgadget.gadgetbridge.Q_SET_MENU_MESSAGE"; + public static final String QHYBRID_COMMAND_SEND_MENU_ITEMS = "nodomain.freeyourgadget.gadgetbridge.Q_SEND_MENU_ITEMS"; + public static final String QHYBRID_COMMAND_SET_WIDGET_CONTENT = "nodomain.freeyourgadget.gadgetbridge.Q_SET_WIDGET_CONTENT"; private static final String QHYBRID_ACTION_SET_ACTIVITY_HAND = "nodomain.freeyourgadget.gadgetbridge.Q_SET_ACTIVITY_HAND"; @@ -91,6 +98,7 @@ public class QHybridSupport extends QHybridBaseSupport { public static final String QHYBRID_EVENT_BUTTON_PRESS = "nodomain.freeyourgadget.gadgetbridge.Q_BUTTON_PRESSED"; public static final String QHYBRID_EVENT_MULTI_BUTTON_PRESS = "nodomain.freeyourgadget.gadgetbridge.Q_MULTI_BUTTON_PRESSED"; + public static final String QHYBRID_EVENT_COMMUTE_MENU = "nodomain.freeyourgadget.gadgetbridge.Q_COMMUTE_MENU"; public static final String ITEM_STEP_GOAL = "STEP_GOAL"; public static final String ITEM_STEP_COUNT = "STEP_COUNT"; @@ -100,13 +108,16 @@ public class QHybridSupport extends QHybridBaseSupport { public static final String ITEM_HAS_ACTIVITY_HAND = "HAS_ACTIVITY_HAND"; public static final String ITEM_USE_ACTIVITY_HAND = "USE_ACTIVITY_HAND"; public static final String ITEM_LAST_HEARTBEAT = "LAST_HEARTBEAT"; - public static final String ITEM_TIMEZONE_OFFSET = "STEPTIMEZONE_OFFSET_COUNT"; + public static final String ITEM_TIMEZONE_OFFSET = "TIMEZONE_OFFSET_COUNT"; + public static final String ITEM_HEART_RATE_MEASUREMENT_MODE = "HEART_RATE_MEASUREMENT_MODE"; private static final Logger logger = LoggerFactory.getLogger(QHybridSupport.class); + private final BroadcastReceiver commandReceiver; + private final BroadcastReceiver globalCommandReceiver; private PackageConfigHelper helper; - private volatile boolean searchDevice = false; + public volatile boolean searchDevice = false; private long timeOffset; @@ -117,9 +128,10 @@ public class QHybridSupport extends QHybridBaseSupport { public QHybridSupport() { super(logger); addSupportedService(UUID.fromString("3dda0001-957f-7d4a-34a6-74696673696d")); - addSupportedService(UUID.fromString("0000180a-0000-1000-8000-00805f9b34fb")); - addSupportedService(UUID.fromString("00001800-0000-1000-8000-00805f9b34fb")); - addSupportedService(UUID.fromString("0000180f-0000-1000-8000-00805f9b34fb")); + addSupportedService(GattService.UUID_SERVICE_DEVICE_INFORMATION); + addSupportedService(GattService.UUID_SERVICE_GENERIC_ACCESS); + addSupportedService(GattService.UUID_SERVICE_HEART_RATE); + addSupportedService(GattService.UUID_SERVICE_BATTERY_SERVICE); IntentFilter commandFilter = new IntentFilter(QHYBRID_COMMAND_CONTROL); commandFilter.addAction(QHYBRID_COMMAND_UNCONTROL); commandFilter.addAction(QHYBRID_COMMAND_SET); @@ -130,12 +142,18 @@ public class QHybridSupport extends QHybridBaseSupport { commandFilter.addAction(QHYBRID_COMMAND_UPDATE_SETTINGS); commandFilter.addAction(QHYBRID_COMMAND_OVERWRITE_BUTTONS); commandFilter.addAction(QHYBRID_COMMAND_NOTIFICATION_CONFIG_CHANGED); - BroadcastReceiver commandReceiver = new BroadcastReceiver() { + commandFilter.addAction(QHYBRID_COMMAND_UPDATE_WIDGETS); + commandFilter.addAction(QHYBRID_COMMAND_SEND_MENU_ITEMS); + commandReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Bundle extras = intent.getExtras(); NotificationConfiguration config = extras == null ? null : (NotificationConfiguration) intent.getExtras().get("CONFIG"); + if (intent.getAction() == null) { + return; + } + switch (intent.getAction()) { case QHYBRID_COMMAND_CONTROL: { log("sending control request"); @@ -152,16 +170,21 @@ public class QHybridSupport extends QHybridBaseSupport { break; } case QHYBRID_COMMAND_SET: { - watchAdapter.setHands(config.getHour(), config.getMin()); - + if (config != null) { + watchAdapter.setHands(config.getHour(), config.getMin()); + } break; } case QHYBRID_COMMAND_VIBRATE: { - watchAdapter.vibrate(config.getVibration()); + if (config != null) { + watchAdapter.vibrate(config.getVibration()); + } break; } case QHYBRID_COMMAND_NOTIFICATION: { - watchAdapter.playNotification(config); + if (config != null) { + watchAdapter.playNotification(config); + } break; } case QHYBRID_COMMAND_UPDATE: { @@ -203,28 +226,25 @@ public class QHybridSupport extends QHybridBaseSupport { watchAdapter.syncNotificationSettings(); break; } + case QHYBRID_COMMAND_UPDATE_WIDGETS: { + watchAdapter.updateWidgets(); + break; + } } } }; LocalBroadcastManager.getInstance(getContext()).registerReceiver(commandReceiver, commandFilter); - try { - helper = new PackageConfigHelper(GBApplication.getContext()); - } catch (GBException e) { - GB.log("error getting database", GB.ERROR, e); - GB.toast("error getting database", Toast.LENGTH_SHORT, GB.ERROR, e); - try { - throw e; - } catch (GBException ex) { - ex.printStackTrace(); - } - } + helper = new PackageConfigHelper(GBApplication.getContext()); IntentFilter globalFilter = new IntentFilter(); globalFilter.addAction(QHYBRID_ACTION_SET_ACTIVITY_HAND); - BroadcastReceiver globalCommandReceiver = new BroadcastReceiver() { + globalFilter.addAction(QHYBRID_COMMAND_SET_MENU_MESSAGE); + globalFilter.addAction(QHYBRID_COMMAND_SET_WIDGET_CONTENT); + globalCommandReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { + if(watchAdapter == null) return; //noinspection SwitchStatementWithTooFewBranches switch (intent.getAction()) { case QHYBRID_ACTION_SET_ACTIVITY_HAND: { @@ -245,12 +265,61 @@ public class QHybridSupport extends QHybridBaseSupport { } break; } + case QHYBRID_COMMAND_SET_MENU_MESSAGE: { + String message = String.valueOf(intent.getExtras().get("EXTRA_MESSAGE")); + boolean finished = Boolean.valueOf(String.valueOf(intent.getExtras().get("EXTRA_FINISHED"))); + + watchAdapter.setCommuteMenuMessage(message, finished); + + break; + } + case QHYBRID_COMMAND_SET_WIDGET_CONTENT: { + HashMap widgetValues = new HashMap<>(); + + for(String key : intent.getExtras().keySet()){ + if(key.matches("^EXTRA_WIDGET_ID_.*$")){ + widgetValues.put(key.substring(16), String.valueOf(intent.getExtras().get(key))); + } + } + boolean render = intent.getBooleanExtra("EXTRA_RENDER", true); + if(widgetValues.size() > 0){ + Iterator valuesIterator = widgetValues.keySet().iterator(); + valuesIterator.next(); + + while(valuesIterator.hasNext()){ + String id = valuesIterator.next(); + watchAdapter.setWidgetContent(id, widgetValues.get(id), false); + } + + valuesIterator = widgetValues.keySet().iterator(); + String id = valuesIterator.next(); + watchAdapter.setWidgetContent(id, widgetValues.get(id), render); + }else { + String id = String.valueOf(intent.getExtras().get("EXTRA_WIDGET_ID")); + String content = String.valueOf(intent.getExtras().get("EXTRA_CONTENT")); + watchAdapter.setWidgetContent(id, content, render); + } + break; + } } } }; GBApplication.getContext().registerReceiver(globalCommandReceiver, globalFilter); } + @Override + public void onSetCallState(CallSpec callSpec) { + super.onSetCallState(callSpec); + watchAdapter.onSetCallState(callSpec); + } + + @Override + public void dispose() { + LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(commandReceiver); + GBApplication.getContext().unregisterReceiver(globalCommandReceiver); + super.dispose(); + } + @Override public void onSetAlarms(ArrayList alarms) { super.onSetAlarms(alarms); @@ -282,8 +351,10 @@ public class QHybridSupport extends QHybridBaseSupport { this.useActivityHand = GBApplication.getPrefs().getBoolean("QHYBRID_USE_ACTIVITY_HAND", false); getDevice().addDeviceInfo(new GenericItem(ITEM_USE_ACTIVITY_HAND, String.valueOf(this.useActivityHand))); - getDevice().setNotificationIconConnected(R.drawable.ic_notification_qhybrid); - getDevice().setNotificationIconDisconnected(R.drawable.ic_notification_disconnected_qhybrid); + if (GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()).getBoolean(DeviceSettingsPreferenceConst.PREF_USE_CUSTOM_DEVICEICON, true)) { + getDevice().setNotificationIconConnected(R.drawable.ic_notification_qhybrid); + getDevice().setNotificationIconDisconnected(R.drawable.ic_notification_disconnected_qhybrid); + } for (int i = 2; i <= 7; i++) builder.notify(getCharacteristic(UUID.fromString("3dda000" + i + "-957f-7d4a-34a6-74696673696d")), true); @@ -292,13 +363,33 @@ public class QHybridSupport extends QHybridBaseSupport { .read(getCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb"))) .read(getCharacteristic(UUID.fromString("00002a26-0000-1000-8000-00805f9b34fb"))) .read(getCharacteristic(UUID.fromString("00002a24-0000-1000-8000-00805f9b34fb"))) + // .notify(getCharacteristic(UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb")), true) ; + loadTimeOffset(); return builder; } + @Override + public void onSetMusicInfo(MusicSpec musicSpec) { + super.onSetMusicInfo(musicSpec); + + try { + watchAdapter.setMusicInfo(musicSpec); + }catch (Exception e){ + GB.log("setMusicInfo error", GB.ERROR, e); + } + } + + @Override + public void onSetMusicState(MusicStateSpec stateSpec) { + super.onSetMusicState(stateSpec); + + watchAdapter.setMusicState(stateSpec); + } + @Override public void onFetchRecordedData(int dataTypes) { if ((dataTypes & RecordedDataTypes.TYPE_ACTIVITY) != 0) { @@ -310,13 +401,17 @@ public class QHybridSupport extends QHybridBaseSupport { public void onNotification(NotificationSpec notificationSpec) { log("notif from " + notificationSpec.sourceAppId + " " + notificationSpec.sender + " " + notificationSpec.phoneNumber); //new Exception().printStackTrace(); + + if(this.watchAdapter instanceof FossilHRWatchAdapter){ + if(((FossilHRWatchAdapter) watchAdapter).playRawNotification(notificationSpec)) return; + } + String packageName = notificationSpec.sourceName; NotificationConfiguration config = null; try { config = helper.getNotificationConfiguration(packageName); - } catch (GBException e) { - GB.log("error getting notification configuration", GB.ERROR, e); + } catch (Exception e) { GB.toast("error getting notification configuration", Toast.LENGTH_SHORT, GB.ERROR, e); } if (config == null) return; @@ -368,9 +463,7 @@ public class QHybridSupport extends QHybridBaseSupport { for (NotificationConfiguration config : helper.getNotificationConfigurations()) { configs.put(config, false); } - } catch (GBException e) { - GB.log("error getting notification configuration", GB.ERROR, e); - + } catch (Exception e) { GB.toast("error getting notification configs", Toast.LENGTH_SHORT, GB.ERROR, e); } @@ -389,6 +482,12 @@ public class QHybridSupport extends QHybridBaseSupport { return notificationProgress; } + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { + super.onConnectionStateChange(gatt, status, newState); + watchAdapter.onConnectionStateChange(gatt, status, newState); + } + //TODO toggle "Notifications when screen on" options on this check private void showNotificationCountOnActivityHand(double progress) { if (useActivityHand) { @@ -416,35 +515,12 @@ public class QHybridSupport extends QHybridBaseSupport { @Override public void onFindDevice(boolean start) { - try { - if (watchAdapter.supportsExtendedVibration()) { - GB.toast("Device does not support brr brr", Toast.LENGTH_SHORT, GB.INFO); - } - } catch (UnsupportedOperationException e) { - notifiyException(e); - GB.toast("Please contact dakhnod@gmail.com\n", Toast.LENGTH_SHORT, GB.INFO); - } + watchAdapter.onFindDevice(start); + } - if (start && searchDevice) return; - - searchDevice = start; - - if (start) { - new Thread(new Runnable() { - @Override - public void run() { - int i = 0; - while (searchDevice) { - QHybridSupport.this.watchAdapter.vibrateFindMyDevicePattern(); - try { - Thread.sleep(2500); - } catch (InterruptedException e) { - GB.log("error", GB.ERROR, e); - } - } - } - }).start(); - } + @Override + public void onSendWeather(WeatherSpec weatherSpec) { + watchAdapter.onSendWeather(weatherSpec); } @Override @@ -454,23 +530,20 @@ public class QHybridSupport extends QHybridBaseSupport { private void backupFile(DownloadFileRequest request) { try { - File f = new File("/sdcard/qFiles/"); - if (!f.exists()) f.mkdir(); - - File file = new File("/sdcard/qFiles/" + request.timeStamp); + File file = FileUtils.getExternalFile("qFiles/" + request.timeStamp); if (file.exists()) { throw new Exception("file " + file.getPath() + " exists"); } logger.debug("Writing file " + file.getPath()); - file.createNewFile(); - FileOutputStream fos = new FileOutputStream(file); - fos.write(request.file); - fos.close(); + try (FileOutputStream fos = new FileOutputStream(file)) { + fos.write(request.file); + } logger.debug("file written."); - FileOutputStream fos2 = new FileOutputStream("/sdcard/qFiles/steps", true); - fos2.write(("file " + request.timeStamp + " cut\n\n").getBytes()); - fos2.close(); + file = FileUtils.getExternalFile("qFiles/steps"); + try (FileOutputStream fos = new FileOutputStream(file, true)) { + fos.write(("file " + request.timeStamp + " cut\n\n").getBytes()); + } //TODO file stuff // queueWrite(new EraseFileRequest((short) request.fileHandle)); @@ -488,6 +561,16 @@ public class QHybridSupport extends QHybridBaseSupport { } public void notifiyException(Exception e){ + notifiyException("", e); + } + + public void notifiyException(String requestName, Exception e) { + if (!BuildConfig.DEBUG) { + logger.error("Error: " + requestName, e); + return; + } + GB.toast("Please contact dakhnod@gmail.com\n", Toast.LENGTH_SHORT, GB.ERROR, e); + StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); @@ -500,7 +583,7 @@ public class QHybridSupport extends QHybridBaseSupport { notificationBuilder = new Notification.Builder(getContext()); } notificationBuilder - .setContentTitle("Q Error") + .setContentTitle("Q Error " + requestName) .setSmallIcon(R.drawable.ic_notification_qhybrid) .setContentText(sStackTrace) .setStyle(new Notification.BigTextStyle()) @@ -520,7 +603,12 @@ public class QHybridSupport extends QHybridBaseSupport { } ((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify((int) System.currentTimeMillis(), notificationBuilder.build()); + } + @Override + public boolean onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + watchAdapter.onCharacteristicWrite(gatt, characteristic, status); + return super.onCharacteristicWrite(gatt, characteristic, status); } @Override @@ -544,7 +632,6 @@ public class QHybridSupport extends QHybridBaseSupport { gbDevice.addDeviceInfo(new GenericItem(ITEM_HAS_ACTIVITY_HAND, String.valueOf(watchAdapter.supportsActivityHand()))); } catch (UnsupportedOperationException e) { notifiyException(e); - GB.toast("Please contact dakhnod@gmail.com\n", Toast.LENGTH_SHORT, GB.INFO); gbDevice.addDeviceInfo(new GenericItem(ITEM_EXTENDED_VIBRATION_SUPPORT, "false")); } break; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java index ff4f0ba39..e6e39b050 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -24,6 +24,10 @@ import java.util.ArrayList; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; +import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; +import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest; @@ -94,4 +98,34 @@ public abstract class WatchAdapter { } return s.substring(0, s.length() - 1) + "\n"; } + + public void setCommuteMenuMessage(String message, boolean finished) { + } + + public void setMusicInfo(MusicSpec musicSpec) { + } + + public void setMusicState(MusicStateSpec stateSpec) { + } + + public void setWidgetContent(String widgetID, String content, boolean render) { + } + + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + } + + public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { + } + + public void updateWidgets() { + } + + public void onSetCallState(CallSpec callSpec) { + } + + public void onFindDevice(boolean start) { + } + + public void onSendWeather(WeatherSpec weatherSpec) { + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapterFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapterFactory.java index 6a29d90ae..1fc64fc7f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapterFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/WatchAdapterFactory.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -18,12 +18,17 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter; 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_hr.FossilHRWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.misfit.MisfitWatchAdapter; public final class WatchAdapterFactory { public final WatchAdapter createWatchAdapter(String firmwareVersion, QHybridSupport deviceSupport){ + char hardwareVersion = firmwareVersion.charAt(2); + if(hardwareVersion == '1') return new FossilHRWatchAdapter(deviceSupport); + char major = firmwareVersion.charAt(6); switch (major){ + case '0': return new MisfitWatchAdapter(deviceSupport); case '1': return new MisfitWatchAdapter(deviceSupport); case '2': return new FossilWatchAdapter(deviceSupport); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java index 679914c70..ab030c145 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -21,14 +21,12 @@ import android.bluetooth.BluetoothGattCharacteristic; import android.content.Intent; import android.content.SharedPreferences; import android.os.Build; -import android.util.Log; import android.widget.Toast; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.json.JSONArray; import org.json.JSONException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.text.DateFormat; import java.util.ArrayList; @@ -37,7 +35,6 @@ import java.util.GregorianCalendar; import java.util.TimeZone; import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; @@ -56,7 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.NotificationFilterPutRequest; -import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayNotificationRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.MoveHandsRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ReleaseHandsControlRequest; @@ -86,7 +83,7 @@ public class FossilWatchAdapter extends WatchAdapter { private int lastButtonIndex = -1; - Logger logger = LoggerFactory.getLogger(getClass()); + protected Logger logger = LoggerFactory.getLogger(getClass().getSimpleName()); public FossilWatchAdapter(QHybridSupport deviceSupport) { super(deviceSupport); @@ -129,6 +126,31 @@ public class FossilWatchAdapter extends WatchAdapter { overwriteButtons(buttonConfig); } + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + if(status != BluetoothGatt.GATT_SUCCESS){ + if(characteristic.getUuid().toString().equals("3dda0005-957f-7d4a-34a6-74696673696d")){ + GB.log("authentication failed", GB.ERROR, null); + setDeviceState(GBDevice.State.AUTHENTICATION_REQUIRED); + requestQueue.clear(); + } + log("characteristic write failed: " + status); + fossilRequest = null; + + queueNextRequest(); + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { + log("status " + status + " newState: " + newState); + if(newState != BluetoothGatt.STATE_CONNECTED){ + log("status " + newState + " clearing queue..."); + requestQueue.clear(); + fossilRequest = null; + } + } + private SharedPreferences getDeviceSpecificPreferences(){ return GBApplication.getDeviceSpecificSharedPrefs( getDeviceSupport().getDevice().getAddress() @@ -172,7 +194,7 @@ public class FossilWatchAdapter extends WatchAdapter { log("package name in notification not set"); return; } - queueWrite(new PlayNotificationRequest(config.getPackageName(), this), false); + queueWrite(new PlayTextNotificationRequest(config.getPackageName(), this), false); } @Override @@ -326,7 +348,7 @@ public class FossilWatchAdapter extends WatchAdapter { getDeviceSupport().getDevice().sendDeviceUpdateIntent(getContext()); } }, false); - } catch (GBException e) { + } catch (Exception e) { GB.log("error", GB.ERROR, e); } } @@ -441,8 +463,13 @@ public class FossilWatchAdapter extends WatchAdapter { handleBackgroundCharacteristic(characteristic); break; } + case "00002a37-0000-1000-8000-00805f9b34fb": { + handleHeartRateCharacteristic(characteristic); + break; + } case "3dda0002-957f-7d4a-34a6-74696673696d": case "3dda0004-957f-7d4a-34a6-74696673696d": + case "3dda0005-957f-7d4a-34a6-74696673696d": case "3dda0003-957f-7d4a-34a6-74696673696d": { if (fossilRequest != null) { boolean requestFinished; @@ -458,8 +485,14 @@ public class FossilWatchAdapter extends WatchAdapter { fossilRequest.handleResponse(characteristic); requestFinished = fossilRequest.isFinished(); } catch (RuntimeException e) { + if(characteristic.getUuid().toString().equals("3dda0005-957f-7d4a-34a6-74696673696d")){ + GB.log("authentication failed", GB.ERROR, null); + setDeviceState(GBDevice.State.AUTHENTICATION_REQUIRED); + requestQueue.clear(); + } + GB.log("error", GB.ERROR, e); - getDeviceSupport().notifiyException(e); + getDeviceSupport().notifiyException(fossilRequest.getName(), e); GB.toast(fossilRequest.getName() + " failed", Toast.LENGTH_SHORT, GB.ERROR); requestFinished = true; } @@ -477,7 +510,42 @@ public class FossilWatchAdapter extends WatchAdapter { return true; } - private void handleBackgroundCharacteristic(BluetoothGattCharacteristic characteristic) { + public void handleHeartRateCharacteristic(BluetoothGattCharacteristic characteristic) { + } + + @Override + public void onFindDevice(boolean start) { + try { + if (this.supportsExtendedVibration()) { + GB.toast("Device does not support brr brr", Toast.LENGTH_SHORT, GB.INFO); + } + } catch (UnsupportedOperationException e) { + getDeviceSupport().notifiyException(e); + } + + if (start && getDeviceSupport().searchDevice) return; + + getDeviceSupport().searchDevice = start; + + if (start) { + new Thread(new Runnable() { + @Override + public void run() { + int i = 0; + while (getDeviceSupport().searchDevice) { + vibrateFindMyDevicePattern(); + try { + Thread.sleep(2500); + } catch (InterruptedException e) { + GB.log("error", GB.ERROR, e); + } + } + } + }).start(); + } + } + + protected void handleBackgroundCharacteristic(BluetoothGattCharacteristic characteristic) { byte[] value = characteristic.getValue(); switch (value[1]) { case 2: { @@ -529,6 +597,11 @@ public class FossilWatchAdapter extends WatchAdapter { public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { super.onMtuChanged(gatt, mtu, status); + if(this.MTU == mtu){ + log("MTU changed, same value tho"); + return; + } + log("MTU changed: " + mtu); this.MTU = mtu; @@ -541,6 +614,11 @@ public class FossilWatchAdapter extends WatchAdapter { } public void queueWrite(RequestMtuRequest request, boolean priorise) { + log("is connected: " + getDeviceSupport().isConnected()); + if(!getDeviceSupport().isConnected()){ + log("dropping requetst " + request.getName()); + return; + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { new TransactionBuilder("requestMtu") .requestMtu(512) @@ -565,12 +643,21 @@ public class FossilWatchAdapter extends WatchAdapter { return; } log("setting device state: " + request.getDeviceState()); - getDeviceSupport().getDevice().setState(request.getDeviceState()); - getDeviceSupport().getDevice().sendDeviceUpdateIntent(getContext()); + setDeviceState(request.getDeviceState()); queueNextRequest(); } + private void setDeviceState(GBDevice.State state){ + getDeviceSupport().getDevice().setState(state); + getDeviceSupport().getDevice().sendDeviceUpdateIntent(getContext()); + } + public void queueWrite(FossilRequest request, boolean priorise) { + log("is connected: " + getDeviceSupport().isConnected()); + if(!getDeviceSupport().isConnected()){ + log("dropping requetst " + request.getName()); + return; + } if (fossilRequest != null && !fossilRequest.isFinished()) { log("queing request: " + request.getName()); if (priorise) { @@ -583,15 +670,30 @@ public class FossilWatchAdapter extends WatchAdapter { log("executing request: " + request.getName()); this.fossilRequest = request; new TransactionBuilder(request.getClass().getSimpleName()).write(getDeviceSupport().getCharacteristic(request.getRequestUUID()), request.getRequestData()).queue(getDeviceSupport().getQueue()); + + if(request.isFinished()){ + this.fossilRequest = null; + queueNextRequest(); + } } public void queueWrite(Request request, boolean priorise) { + log("is connected: " + getDeviceSupport().isConnected()); + if(!getDeviceSupport().isConnected()){ + log("dropping requetst " + request.getName()); + return; + } new TransactionBuilder(request.getClass().getSimpleName()).write(getDeviceSupport().getCharacteristic(request.getRequestUUID()), request.getRequestData()).queue(getDeviceSupport().getQueue()); queueNextRequest(); } - void queueWrite(Request request) { + protected void queueWrite(Request request) { + log("is connected: " + getDeviceSupport().isConnected()); + if(!getDeviceSupport().isConnected()){ + log("dropping requetst " + request.getName()); + return; + } if (request instanceof SetDeviceStateRequest) queueWrite((SetDeviceStateRequest) request, false); else if (request instanceof RequestMtuRequest) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java new file mode 100644 index 000000000..a51cbf9b7 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -0,0 +1,839 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr; + +import android.bluetooth.BluetoothGattCharacteristic; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.os.Build; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.io.IOException; +import java.nio.BufferOverflowException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.TimeZone; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicControl; +import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HRConfigActivity; +import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationHRConfiguration; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; +import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; +import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; +import nodomain.freeyourgadget.gadgetbridge.model.Weather; +import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +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.requests.fossil.RequestMtuRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.TimeConfigItem; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayCallNotificationRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.VerifyPrivateKeyRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons.ButtonConfigurationPutRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration.ConfigurationGetRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration.ConfigurationPutRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFilePutRequest; +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.ImagesSetRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.json.JsonPutRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.menu.SetCommuteMenuMessage; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicInfoSetRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification.NotificationFilterPutHRRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomBackgroundWidgetElement; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomTextWidgetElement; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomWidget; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomWidgetElement; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.Widget; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.WidgetsPutRequest; +import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; + +import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest.MUSIC_PHONE_REQUEST; +import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest.MUSIC_WATCH_REQUEST; + +public class FossilHRWatchAdapter extends FossilWatchAdapter { + private byte[] phoneRandomNumber; + private byte[] watchRandomNumber; + + private ArrayList widgets = new ArrayList<>(); + + private NotificationHRConfiguration[] notificationConfigurations; + + private MusicSpec currentSpec = null; + + int imageNameIndex = 0; + private byte jsonIndex = 0; + + private AssetImage backGroundImage = null; + + public FossilHRWatchAdapter(QHybridSupport deviceSupport) { + super(deviceSupport); + } + + @Override + public void initialize() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + queueWrite(new RequestMtuRequest(512)); + } + + queueWrite(new SetDeviceStateRequest(GBDevice.State.AUTHENTICATING)); + + negotiateSymmetricKey(); + + queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZING)); + + loadNotificationConfigurations(); + queueWrite(new NotificationFilterPutHRRequest(this.notificationConfigurations, this)); + setVibrationStrength((short) 75); + + syncSettings(); + + setTime(); + + overwriteButtons(null); + + + loadBackground(); + loadWidgets(); + // renderWidgets(); + // dunno if there is any point in doing this at start since when no watch is connected the QHybridSupport will not receive any intents anyway + + queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED)); + } + + @Override + public void setVibrationStrength(short strength) { + negotiateSymmetricKey(); + queueWrite(new ConfigurationPutRequest(new nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.VibrationStrengthConfigItem((byte) strength), this)); + } + + private void loadNotificationConfigurations(){ + this.notificationConfigurations = new NotificationHRConfiguration[]{ + new NotificationHRConfiguration("generic", 0), + new NotificationHRConfiguration("call", new byte[]{(byte)0x80, (byte) 0x00, (byte) 0x59, (byte) 0xB7}, 0) + }; + } + + private void loadBackground(){ + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress())); + boolean forceWhiteBackground = prefs.getBoolean("force_white_color_scheme", false); + if (forceWhiteBackground) { + byte[] whiteGIF = new byte[]{ + 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x01, 0x00, 0x01, 0x00, (byte) 0x80, 0x01, 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3B + }; + + Bitmap backgroundBitmap = BitmapFactory.decodeByteArray(whiteGIF, 0, whiteGIF.length); + //Bitmap backgroundBitmap = BitmapFactory.decodeFile("/sdcard/DCIM/Camera/IMG_20191129_200726.jpg"); + + try { + this.backGroundImage = AssetImageFactory.createAssetImage(backgroundBitmap, false, 0, 0, 0); + } catch (IOException e) { + logger.error("Backgroundimage error", e); + } + } + } + + private void loadWidgets() { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress())); + boolean forceWhiteBackground = prefs.getBoolean("force_white_color_scheme", false); + String fontColor = forceWhiteBackground ? "black" : "default"; + + this.widgets.clear(); + String widgetJson = GBApplication.getPrefs().getPreferences().getString("FOSSIL_HR_WIDGETS", "{}"); + String customWidgetJson = GBApplication.getPrefs().getString("QHYBRID_CUSTOM_WIDGETS", "[]"); + + try { + JSONObject widgetConfig = new JSONObject(widgetJson); + JSONArray customWidgets = new JSONArray(customWidgetJson); + + Iterator keyIterator = widgetConfig.keys(); + HashMap positionMap = new HashMap<>(4); + positionMap.put("top", 0); + positionMap.put("right", 90); + positionMap.put("bottom", 180); + positionMap.put("left", 270); + + while(keyIterator.hasNext()){ + String position = keyIterator.next(); + String identifier = widgetConfig.getString(position); + Widget.WidgetType type = Widget.WidgetType.fromJsonIdentifier(identifier); + + Widget widget = null; + if(type != null) { + widget = new Widget(type, positionMap.get(position), 63, fontColor); + }else{ + identifier = identifier.substring(7); + for(int i = 0; i < customWidgets.length(); i++){ + JSONObject customWidget = customWidgets.getJSONObject(i); + if(customWidget.getString("name").equals(identifier)){ + CustomWidget newWidget = new CustomWidget( + customWidget.getString("name"), + positionMap.get(position), + 63, + fontColor + ); + JSONArray elements = customWidget.getJSONArray("elements"); + + for (int i2 = 0; i2 < elements.length(); i2++) { + JSONObject element = elements.getJSONObject(i2); + if (element.getString("type").equals("text")) { + newWidget.addElement(new CustomTextWidgetElement( + element.getString("id"), + element.getString("value"), + element.getInt("x"), + element.getInt("y") + )); + } else if (element.getString("type").equals("background")) { + newWidget.addElement(new CustomBackgroundWidgetElement( + element.getString("id"), + element.getString("value") + )); + } + } + widget = newWidget; + } + } + } + + if(widget == null) continue; + this.widgets.add(widget); + } + } catch (JSONException e) { + e.printStackTrace(); + } + + uploadWidgets(); + } + + private void uploadWidgets(){ + negotiateSymmetricKey(); + ArrayList systemWidgets = new ArrayList<>(widgets.size()); + for(Widget widget : this.widgets){ + if(!(widget instanceof CustomWidget)) systemWidgets.add(widget); + } + queueWrite(new WidgetsPutRequest(systemWidgets.toArray(new Widget[0]), this)); + } + + private void renderWidgets() { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress())); + boolean forceWhiteBackground = prefs.getBoolean("force_white_color_scheme", false); + try { + ArrayList widgetImages = new ArrayList<>(); + + if(this.backGroundImage != null){ + widgetImages.add(this.backGroundImage); + } + + + for (int i = 0; i < this.widgets.size(); i++) { + Widget w = widgets.get(i); + if(!(w instanceof CustomWidget)) continue; + CustomWidget widget = (CustomWidget) w; + + Bitmap widgetBitmap = Bitmap.createBitmap(76, 76, Bitmap.Config.ARGB_8888); + + Canvas widgetCanvas = new Canvas(widgetBitmap); + + boolean backgroundDrawn = false; + + Paint circlePaint = new Paint(); + if(!backgroundDrawn){ + circlePaint.setColor(forceWhiteBackground ? Color.WHITE : Color.BLACK); + circlePaint.setStyle(Paint.Style.FILL); + circlePaint.setStrokeWidth(3); + widgetCanvas.drawCircle(38, 38, 37, circlePaint); + + circlePaint.setColor(forceWhiteBackground ? Color.BLACK : Color.WHITE); + circlePaint.setStyle(Paint.Style.STROKE); + circlePaint.setStrokeWidth(3); + widgetCanvas.drawCircle(38, 38, 37, circlePaint); + } + + for (CustomWidgetElement element : widget.getElements()) { + if (element.getWidgetElementType() == CustomWidgetElement.WidgetElementType.TYPE_BACKGROUND) { + File imageFile = new File(element.getValue()); + + if(!imageFile.exists() || !imageFile.isFile()){ + logger.debug("Image file " + element.getValue() + " not found"); + continue; + } + Bitmap imageBitmap = BitmapFactory.decodeFile(element.getValue()); + if(imageBitmap == null){ + logger.debug("image file " + element.getValue() + " could not be decoded"); + continue; + } + Bitmap scaledBitmap = Bitmap.createScaledBitmap(imageBitmap, 76, 76, false); + + widgetCanvas.drawBitmap( + scaledBitmap, + 0, + 0, + null); + backgroundDrawn = true; + break; + } + } + + for (CustomWidgetElement element : widget.getElements()) { + if (element.getWidgetElementType() == CustomWidgetElement.WidgetElementType.TYPE_TEXT) { + Paint textPaint = new Paint(); + textPaint.setStrokeWidth(4); + textPaint.setTextSize(17f); + textPaint.setStyle(Paint.Style.FILL); + textPaint.setColor(forceWhiteBackground ? Color.BLACK : Color.WHITE); + textPaint.setTextAlign(Paint.Align.CENTER); + + widgetCanvas.drawText(element.getValue(), element.getX(), element.getY() - (textPaint.descent() + textPaint.ascent()) / 2f, textPaint); + }else if(element.getWidgetElementType() == CustomWidgetElement.WidgetElementType.TYPE_IMAGE) { + Bitmap imageBitmap = BitmapFactory.decodeFile(element.getValue()); + + widgetCanvas.drawBitmap(imageBitmap, element.getX() - imageBitmap.getWidth() / 2f, element.getY() - imageBitmap.getHeight() / 2f, null); + } + } + widgetImages.add(AssetImageFactory.createAssetImage( + widgetBitmap, + true, + widget.getAngle(), + widget.getDistance(), + 1 + )); + } + + AssetImage[] images = widgetImages.toArray(new AssetImage[0]); + + // queueWrite(new FileDeleteRequest((short) 0x0700)); + queueWrite(new AssetFilePutRequest( + images, + (byte) 0x00, + this + )); + + // queueWrite(new FileDeleteRequest((short) 0x0503)); + queueWrite(new ImagesSetRequest( + images, + this + )); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void setWidgetContent(String widgetID, String content, boolean renderOnWatch) { + boolean update = false; + for (Widget widget : this.widgets) { + if(!(widget instanceof CustomWidget)) continue; + if(((CustomWidget) widget).updateElementValue(widgetID, content)) update = true; + } + + if (renderOnWatch && update) renderWidgets(); + } + + private void negotiateSymmetricKey() { + queueWrite(new VerifyPrivateKeyRequest( + this.getSecretKey(), + this + )); + } + + @Override + public void setTime() { + negotiateSymmetricKey(); + + long millis = System.currentTimeMillis(); + TimeZone zone = new GregorianCalendar().getTimeZone(); + + queueWrite( + new ConfigurationPutRequest( + new TimeConfigItem( + (int) (millis / 1000 + getDeviceSupport().getTimeOffset() * 60), + (short) (millis % 1000), + (short) (zone.getOffset(millis) / 60000) + ), + this), false + ); + } + + @Override + public void setMusicInfo(MusicSpec musicSpec) { + if ( + currentSpec != null + && currentSpec.album.equals(musicSpec.album) + && currentSpec.artist.equals(musicSpec.artist) + && currentSpec.track.equals(musicSpec.track) + ) return; + currentSpec = musicSpec; + try { + queueWrite(new MusicInfoSetRequest( + musicSpec.artist, + musicSpec.album, + musicSpec.track, + this + )); + }catch (BufferOverflowException e){ + GB.log("musicInfo: " + musicSpec, GB.ERROR, e); + } + } + + @Override + public void setMusicState(MusicStateSpec stateSpec) { + super.setMusicState(stateSpec); + + queueWrite(new MusicControlRequest( + stateSpec.state == MusicStateSpec.STATE_PLAYING ? MUSIC_PHONE_REQUEST.MUSIC_REQUEST_SET_PLAYING : MUSIC_PHONE_REQUEST.MUSIC_REQUEST_SET_PAUSED + )); + } + + @Override + public void updateWidgets() { + loadWidgets(); + renderWidgets(); + } + + @Override + public void onFetchActivityData() { + syncSettings(); + } + + private void syncSettings() { + negotiateSymmetricKey(); + + queueWrite(new ConfigurationGetRequest(this)); + } + + @Override + public void setActivityHand(double progress) { + // super.setActivityHand(progress); + } + + public boolean playRawNotification(NotificationSpec notificationSpec) { + String senderOrTitle = StringUtils.getFirstOf(notificationSpec.sender, notificationSpec.title); + + try { + for (NotificationHRConfiguration configuration : this.notificationConfigurations){ + if(configuration.getPackageName().equals(notificationSpec.sourceAppId)){ + queueWrite(new PlayTextNotificationRequest(notificationSpec.sourceAppId, senderOrTitle, notificationSpec.body, this)); + return true; + } + } + queueWrite(new PlayTextNotificationRequest("generic", senderOrTitle, notificationSpec.body, this)); + }catch (Exception e){ + e.printStackTrace(); + } + return true; + } + + @Override + public void onFindDevice(boolean start) { + if(start){ + new TransactionBuilder("vibrate find") + .write( + getDeviceSupport().getCharacteristic(UUID.fromString("3dda0005-957f-7d4a-34a6-74696673696d")), + new byte[]{(byte) 0x01, (byte) 0x04, (byte) 0x30, (byte) 0x75, (byte) 0x00, (byte) 0x00} + ) + .queue(getDeviceSupport().getQueue()); + }else{ + new TransactionBuilder("vibrate find") + .write( + getDeviceSupport().getCharacteristic(UUID.fromString("3dda0005-957f-7d4a-34a6-74696673696d")), + new byte[]{(byte) 0x02, (byte) 0x05, (byte) 0x04} + ) + .queue(getDeviceSupport().getQueue()); + } + } + + @Override + public void onSetCallState(CallSpec callSpec) { + super.onSetCallState(callSpec); + queueWrite(new PlayCallNotificationRequest(StringUtils.getFirstOf(callSpec.name, callSpec.number), callSpec.command == CallSpec.CALL_INCOMING, this)); + } + + // this method is based on the one from AppMessageHandlerYWeather.java + private int getIconForConditionCode(int conditionCode, boolean isNight) { + final int CLEAR_DAY = 0; + final int CLEAR_NIGHT = 1; + final int CLOUDY = 2; + final int PARTLY_CLOUDY_DAY = 3; + final int PARTLY_CLOUDY_NIGHT = 4; + final int RAIN = 5; + final int SNOW = 6; + final int SNOW_2 = 7; // same as 6? + final int THUNDERSTORM = 8; + final int CLOUDY_2 = 9; // same as 2? + final int WINDY = 10; + + if (conditionCode == 800 || conditionCode == 951) { + return isNight ? CLEAR_NIGHT : CLEAR_DAY; + } else if (conditionCode > 800 && conditionCode < 900) { + return isNight ? PARTLY_CLOUDY_NIGHT : PARTLY_CLOUDY_DAY; + } else if (conditionCode >= 300 && conditionCode < 400) { + return RAIN; // drizzle mapped to rain + } else if (conditionCode >= 500 && conditionCode < 600) { + return RAIN; + } else if (conditionCode >= 700 && conditionCode < 732) { + return CLOUDY; + } else if (conditionCode == 741 || conditionCode == 751 || conditionCode == 761 || conditionCode == 762) { + return CLOUDY; // fog mapped to cloudy + } else if (conditionCode == 771) { + return CLOUDY; // squalls mapped to cloudy + } else if (conditionCode == 781) { + return WINDY; // tornato mapped to windy + } else if (conditionCode >= 200 && conditionCode < 300) { + return THUNDERSTORM; + } else if (conditionCode >= 600 && conditionCode <= 602) { + return SNOW; + } else if (conditionCode >= 611 && conditionCode <= 622) { + return RAIN; + } else if (conditionCode == 906) { + return RAIN; // hail mapped to rain + } else if (conditionCode >= 907 && conditionCode < 957) { + return WINDY; + } else if (conditionCode == 905) { + return WINDY; + } else if (conditionCode == 900) { + return WINDY; + } else if (conditionCode == 901 || conditionCode == 902 || conditionCode == 962) { + return WINDY; + } + return isNight ? CLEAR_NIGHT : CLEAR_DAY; + } + + @Override + public void onSendWeather(WeatherSpec weatherSpec) { + long ts = System.currentTimeMillis(); + ts /= 1000; + try { + JSONObject responseObject = new JSONObject() + .put("res", new JSONObject() + .put("id", 0) // seems the id does not matter? + .put("set", new JSONObject() + .put("weatherInfo", new JSONObject() + .put("alive", ts + 60 * 60) + .put("unit", "c") // FIXME: do not hardcode + .put("temp", weatherSpec.currentTemp - 273) + .put("cond_id", getIconForConditionCode(weatherSpec.currentConditionCode, false)) // FIXME do not assume daylight + ) + ) + ); + + queueWrite(new JsonPutRequest(responseObject, this)); + + JSONArray forecastWeekArray = new JSONArray(); + final String[] weekdays = {"", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(weatherSpec.timestamp * 1000L); + int i = 0; + for (WeatherSpec.Forecast forecast : weatherSpec.forecasts) { + cal.add(Calendar.DATE, 1); + int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); + forecastWeekArray.put(new JSONObject() + .put("day", weekdays[dayOfWeek]) + .put("cond_id", getIconForConditionCode(forecast.conditionCode, false)) // FIXME do not assume daylight + .put("high", forecast.maxTemp - 273) + .put("low", forecast.minTemp - 273) + ); + if (++i == 3) break; // max 3 + } + + JSONArray forecastDayArray = new JSONArray(); + final int[] hours = {0, 0, 0}; + + for (int hour : hours) { + forecastDayArray.put(new JSONObject() + .put("hour", hour) + .put("cond_id", 0) + .put("temp", 0) + ); + } + + + JSONObject forecastResponseObject = new JSONObject() + .put("res", new JSONObject() + .put("id", 0) + .put("set", new JSONObject() + .put("weatherApp._.config.locations", new JSONArray() + .put(new JSONObject() + .put("alive", ts + 60 * 60) + .put("city", weatherSpec.location) + .put("unit", "c") // FIXME: do not hardcode + .put("temp", weatherSpec.currentTemp - 273) + .put("high", weatherSpec.todayMaxTemp - 273) + .put("low", weatherSpec.todayMinTemp - 273) + .put("rain", 0) + .put("cond_id", getIconForConditionCode(weatherSpec.currentConditionCode, false)) // FIXME do not assume daylight + .put("forecast_day", forecastDayArray) + .put("forecast_week", forecastWeekArray) + ) + ) + ) + ); + + queueWrite(new JsonPutRequest(forecastResponseObject, this)); + + } catch (JSONException e) { + logger.error("JSON exception: ", e); + } + } + + + // this was used to enumerate the weather icons :) + /* + static int i = 0; + + @Override + public void onTestNewFunction() { + long ts = System.currentTimeMillis(); + ts /= 1000; + try { + JSONObject responseObject = new JSONObject() + .put("res", new JSONObject() + .put("id", 0) // seems the id does not matter? + .put("set", new JSONObject() + .put("weatherInfo", new JSONObject() + .put("alive", ts + 60 * 60) + .put("unit", "c") + .put("temp", i) + .put("cond_id", i++) + ) + )); + + queueWrite(new JsonPutRequest(responseObject, this)); + + } catch (JSONException e) { + logger.error(" JSON exception: ", e); + } + } +*/ + public byte[] getSecretKey() { + byte[] authKeyBytes = new byte[16]; + + SharedPreferences sharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress()); + + String authKey = sharedPrefs.getString("authkey", null); + if (authKey != null && !authKey.isEmpty()) { + byte[] srcBytes = authKey.trim().getBytes(); + if (authKey.length() == 34 && authKey.startsWith("0x")) { + srcBytes = GB.hexStringToByteArray(authKey.substring(2)); + } + System.arraycopy(srcBytes, 0, authKeyBytes, 0, Math.min(srcBytes.length, 16)); + } + + return authKeyBytes; + } + + public void setPhoneRandomNumber(byte[] phoneRandomNumber) { + this.phoneRandomNumber = phoneRandomNumber; + } + + public byte[] getPhoneRandomNumber() { + return phoneRandomNumber; + } + + public void setWatchRandomNumber(byte[] watchRandomNumber) { + this.watchRandomNumber = watchRandomNumber; + } + + public byte[] getWatchRandomNumber() { + return watchRandomNumber; + } + + @Override + public void overwriteButtons(String jsonConfigString) { + try { + JSONArray jsonArray = new JSONArray( + GBApplication.getPrefs().getString(HRConfigActivity.CONFIG_KEY_Q_ACTIONS, "[]") + ); + String[] menuItems = new String[jsonArray.length()]; + for (int i = 0; i < jsonArray.length(); i++) menuItems[i] = jsonArray.getString(i); + + queueWrite(new ButtonConfigurationPutRequest( + menuItems, + this + )); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void handleHeartRateCharacteristic(BluetoothGattCharacteristic characteristic) { + super.handleHeartRateCharacteristic(characteristic); + + byte[] value = characteristic.getValue(); + + int heartRate = value[1]; + + logger.debug("heart rate: " + heartRate); + } + + @Override + protected void handleBackgroundCharacteristic(BluetoothGattCharacteristic characteristic) { + super.handleBackgroundCharacteristic(characteristic); + + byte[] value = characteristic.getValue(); + + byte requestType = value[1]; + + if(requestType == (byte) 0x04){ + handleCallRequest(value); + }else if (requestType == (byte) 0x05) { + handleMusicRequest(value); + } else if (requestType == (byte) 0x01) { + int eventId = value[2]; + logger.info("got event id " + eventId); + try { + String jsonString = new String(value, 3, value.length - 3); + logger.info(jsonString); + JSONObject requestJson = new JSONObject(jsonString); + + JSONObject request = requestJson.getJSONObject("req"); + int requestId = request.getInt("id"); + + if (request.has("ringMyPhone")) { + String action = request.getJSONObject("ringMyPhone").getString("action"); + logger.info("got ringMyPhone request; " + action); + GBDeviceEventFindPhone findPhoneEvent = new GBDeviceEventFindPhone(); + + JSONObject responseObject = new JSONObject() + .put("res", new JSONObject() + .put("id", requestId) + .put("set", new JSONObject() + .put("ringMyPhone", new JSONObject() + ) + ) + ); + + if ("on".equals(action)) { + findPhoneEvent.event = GBDeviceEventFindPhone.Event.START; + getDeviceSupport().evaluateGBDeviceEvent(findPhoneEvent); + responseObject + .getJSONObject("res") + .getJSONObject("set") + .getJSONObject("ringMyPhone") + .put("result", "on"); + queueWrite(new JsonPutRequest(responseObject, this)); + } else if ("off".equals(action)) { + findPhoneEvent.event = GBDeviceEventFindPhone.Event.STOP; + getDeviceSupport().evaluateGBDeviceEvent(findPhoneEvent); + responseObject + .getJSONObject("res") + .getJSONObject("set") + .getJSONObject("ringMyPhone") + .put("result", "off"); + queueWrite(new JsonPutRequest(responseObject, this)); + } + } else if (request.has("weatherInfo") || request.has("weatherApp._.config.locations")) { + logger.info("Got weatherInfo request"); + WeatherSpec weatherSpec = Weather.getInstance().getWeatherSpec(); + if (weatherSpec != null) { + onSendWeather(weatherSpec); + } else { + logger.info("no weather data available - ignoring request"); + } + } else if (request.has("commuteApp._.config.commute_info")) { + String action = request.getJSONObject("commuteApp._.config.commute_info") + .getString("dest"); + + String startStop = request.getJSONObject("commuteApp._.config.commute_info") + .getString("action"); + + if (startStop.equals("stop")) { + // overwriteButtons(null); + return; + } + + queueWrite(new SetCommuteMenuMessage("Anfrage wird weitergeleitet...", false, this)); + + Intent menuIntent = new Intent(QHybridSupport.QHYBRID_EVENT_COMMUTE_MENU); + menuIntent.putExtra("EXTRA_ACTION", action); + getContext().sendBroadcast(menuIntent); + } else { + logger.warn("Unhandled request from watch: " + requestJson.toString()); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + + private void handleCallRequest(byte[] value) { + boolean acceptCall = value[7] == (byte) 0x00; + queueWrite(new PlayCallNotificationRequest("", false, this)); + + GBDeviceEventCallControl callControlEvent = new GBDeviceEventCallControl(); + callControlEvent.event = acceptCall ? GBDeviceEventCallControl.Event.START : GBDeviceEventCallControl.Event.REJECT; + + getDeviceSupport().evaluateGBDeviceEvent(callControlEvent); + } + + private void handleMusicRequest(byte[] value) { + byte command = value[3]; + logger.info("got music command: " + command); + MUSIC_WATCH_REQUEST request = MUSIC_WATCH_REQUEST.fromCommandByte(command); + + GBDeviceEventMusicControl deviceEventMusicControl = new GBDeviceEventMusicControl(); + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PLAY; + + // TODO add skipping/seeking + + switch (request) { + case MUSIC_REQUEST_PLAY_PAUSE: { + queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_PLAY_PAUSE)); + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PLAYPAUSE; + break; + } + case MUSIC_REQUEST_NEXT: { + queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_NEXT)); + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.NEXT; + break; + } + case MUSIC_REQUEST_PREVIOUS: { + queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_PREVIOUS)); + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PREVIOUS; + break; + } + case MUSIC_REQUEST_LOUDER: { + queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_LOUDER)); + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.VOLUMEUP; + break; + } + case MUSIC_REQUEST_QUITER: { + queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_QUITER)); + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.VOLUMEDOWN; + break; + } + } + + getDeviceSupport().evaluateGBDeviceEvent(deviceEventMusicControl); + } + + @Override + public void setCommuteMenuMessage(String message, boolean finished) { + queueWrite(new SetCommuteMenuMessage(message, finished, this)); + } + + public byte getJsonIndex() { + return jsonIndex++; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/misfit/MisfitWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/misfit/MisfitWatchAdapter.java index fb94e92f9..3523134c6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/misfit/MisfitWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/misfit/MisfitWatchAdapter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -74,6 +74,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.mis import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetVibrationStrengthRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.UploadFileRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.VibrateRequest; +import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.ITEM_ACTIVITY_POINT; @@ -92,7 +93,7 @@ public class MisfitWatchAdapter extends WatchAdapter { private Queue requestQueue = new ArrayDeque<>(); - Logger logger = LoggerFactory.getLogger(getClass()); + private Logger logger = LoggerFactory.getLogger(getClass()); public MisfitWatchAdapter(QHybridSupport deviceSupport) { super(deviceSupport); @@ -178,13 +179,10 @@ public class MisfitWatchAdapter extends WatchAdapter { default: { log("unknown shit on " + characteristic.getUuid().toString() + ": " + arrayToString(characteristic.getValue())); try { - File charLog = new File("/sdcard/qFiles/charLog.txt"); - if (!charLog.exists()) { - charLog.createNewFile(); + File charLog = FileUtils.getExternalFile("qFiles/charLog.txt"); + try (FileOutputStream fos = new FileOutputStream(charLog, true)) { + fos.write((new Date().toString() + ": " + characteristic.getUuid().toString() + ": " + arrayToString(characteristic.getValue())).getBytes()); } - - FileOutputStream fos = new FileOutputStream(charLog, true); - fos.write((new Date().toString() + ": " + characteristic.getUuid().toString() + ": " + arrayToString(characteristic.getValue())).getBytes()); } catch (IOException e) { GB.log("error", GB.ERROR, e); } @@ -245,17 +243,11 @@ public class MisfitWatchAdapter extends WatchAdapter { int steps = ((GetCurrentStepCountRequest) request).steps; logger.debug("get current steps: " + steps); try { - File f = new File("/sdcard/qFiles/"); - if (!f.exists()) f.mkdir(); - - File file = new File("/sdcard/qFiles/steps"); - if (!file.exists()) { - file.createNewFile(); - } + File file = FileUtils.getExternalFile("qFiles/steps"); logger.debug("Writing file " + file.getPath()); - FileOutputStream fos = new FileOutputStream(file, true); - fos.write((System.currentTimeMillis() + ": " + steps + "\n").getBytes()); - fos.close(); + try (FileOutputStream fos = new FileOutputStream(file, true)) { + fos.write((System.currentTimeMillis() + ": " + steps + "\n").getBytes()); + } logger.debug("file written."); } catch (Exception e) { GB.log("error", GB.ERROR, e); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigFileBuilder.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigFileBuilder.java index e81c69472..4130989ab 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigFileBuilder.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigFileBuilder.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigPayload.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigPayload.java index 5bc76aa9b..48de212b7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigPayload.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/buttonconfig/ConfigPayload.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/encoder/RLEEncoder.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/encoder/RLEEncoder.java new file mode 100644 index 000000000..96efc49a0 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/encoder/RLEEncoder.java @@ -0,0 +1,34 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.encoder; + +import java.io.ByteArrayOutputStream; + +public class RLEEncoder { + public static byte[] RLEEncode(byte[] data) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length * 2); + + int lastByte = data[0]; + int count = 1; + byte currentByte = -1; + + for (int i = 1; i < data.length; i++) { + currentByte = data[i]; + + if (currentByte != lastByte || count >= 255) { + bos.write(count); + bos.write(data[i - 1]); + + count = 1; + lastByte = data[i]; + } else { + count++; + } + } + + bos.write(count); + bos.write(currentByte); + + byte[] result = bos.toByteArray(); + + return result; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/Request.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/Request.java index 2e7c32e55..32b4d39bd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/Request.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/Request.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -59,7 +59,7 @@ public abstract class Request { public abstract byte[] getStartSequence(); - public void handleResponse(BluetoothGattCharacteristic characteristic){}; + public void handleResponse(BluetoothGattCharacteristic characteristic) {} public String getName(){ Class thisClass = getClass(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/FossilRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/FossilRequest.java index b7353d8f8..4ed716c8b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/FossilRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/FossilRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/RequestMtuRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/RequestMtuRequest.java index 0d67a6bee..20c4bf0d5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/RequestMtuRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/RequestMtuRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/SetDeviceStateRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/SetDeviceStateRequest.java index f7452433a..1baac8bad 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/SetDeviceStateRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/SetDeviceStateRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/Alarm.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/Alarm.java index 9e488d512..980a9a2fb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/Alarm.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/Alarm.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsGetRequest.java index 90d9ebf83..49600773c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsGetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsGetRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsSetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsSetRequest.java index 5ff8465b2..f3e1e274d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsSetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/alarm/AlarmsSetRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/button/ButtonConfigurationGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/button/ButtonConfigurationGetRequest.java index 511aeb930..0241b3a7d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/button/ButtonConfigurationGetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/button/ButtonConfigurationGetRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationGetRequest.java index 491de887f..679832df2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationGetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationGetRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationPutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationPutRequest.java index 3e3535f9d..f5fd7a276 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationPutRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/configuration/ConfigurationPutRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -23,6 +23,7 @@ import java.nio.ByteOrder; import java.util.ArrayList; import java.util.HashMap; +import nodomain.freeyourgadget.gadgetbridge.model.GenericItem; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileCloseAndPutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; @@ -32,14 +33,15 @@ public class ConfigurationPutRequest extends FilePutRequest { private static HashMap> 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); + itemsById.put((short)0x02, CurrentStepCountConfigItem.class); + itemsById.put((short)0x03, DailyStepGoalConfigItem.class); + itemsById.put((short)0x0A, VibrationStrengthConfigItem.class); + itemsById.put((short)0x0C, TimeConfigItem.class); + itemsById.put((short)0x0D, BatteryConfigItem.class); + itemsById.put((short)0x0E, HeartRateMeasurementModeItem.class); } - static ConfigItem[] parsePayload(byte[] data) { + public static ConfigItem[] parsePayload(byte[] data) { ByteBuffer buffer = ByteBuffer.wrap(data); buffer.order(ByteOrder.LITTLE_ENDIAN); @@ -192,6 +194,52 @@ public class ConfigurationPutRequest extends FilePutRequest { } } + static public class BatteryConfigItem extends ConfigItem{ + private int batteryPercentage, batteryVoltage; + + public int getBatteryPercentage() { + return batteryPercentage; + } + + public int getBatteryVoltage() { + return batteryVoltage; + } + + @Override + public int getItemSize() { + return 3; + } + + @Override + public short getId() { + return 0x0D; + } + + @Override + public byte[] getContent() { + return new byte[0]; + } + + @Override + public void parseData(byte[] data) { + ByteBuffer buffer = ByteBuffer.wrap(data); + buffer.order(ByteOrder.LITTLE_ENDIAN); + + this.batteryVoltage = buffer.getShort(); + this.batteryPercentage = buffer.get(); + } + } + + static public class HeartRateMeasurementModeItem extends GenericConfigItem{ + public HeartRateMeasurementModeItem() { + this((byte)-1); + } + + public HeartRateMeasurementModeItem(byte value) { + super((short) 14, value); + } + } + static public class DailyStepGoalConfigItem extends GenericConfigItem { public DailyStepGoalConfigItem(){ this(-1); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/connection/SetConnectionParametersRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/connection/SetConnectionParametersRequest.java index 99459cafb..e31038b72 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/connection/SetConnectionParametersRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/connection/SetConnectionParametersRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileCloseAndPutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileCloseAndPutRequest.java index ad45b776e..4a1315ab7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileCloseAndPutRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileCloseAndPutRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileCloseRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileCloseRequest.java index 7bb3e292f..0f7a077b1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileCloseRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileCloseRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -24,6 +24,7 @@ import java.util.UUID; 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_hr.file.ResultCode; public class FileCloseRequest extends FossilRequest { private boolean isFinished = false; @@ -64,7 +65,8 @@ public class FileCloseRequest extends FossilRequest { byte status = buffer.get(3); - if(status != 0) throw new RuntimeException("wrong response status"); + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()) throw new RuntimeException("wrong response status: " + code + " (" + status + ")"); this.isFinished = true; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileDeleteRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileDeleteRequest.java index 37ea92c44..c64353bcd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileDeleteRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileDeleteRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -22,6 +22,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.ResultCode; public class FileDeleteRequest extends FossilRequest { private boolean finished = false; @@ -53,7 +54,9 @@ public class FileDeleteRequest extends FossilRequest { if(buffer.getShort(1) != this.handle) throw new RuntimeException("wrong response handle"); - if(buffer.get(3) != 0) throw new RuntimeException("wrong response status: " + buffer.get(3)); + byte status = buffer.get(3); + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()) throw new RuntimeException("wrong response status: " + code + "(" + status + ")"); this.finished = true; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileGetRequest.java index 87c87165a..120878a87 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileGetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileGetRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -28,6 +28,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSuppo import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; 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_hr.file.ResultCode; public abstract class FileGetRequest extends FossilRequest { private short handle; @@ -74,8 +75,9 @@ public abstract class FileGetRequest extends FossilRequest { byte status = buffer.get(3); - if(status != 0){ - throw new RuntimeException("FileGet error: " + status); + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()){ + throw new RuntimeException("FileGet error: " + code + " (" + status + ")"); } if(this.handle != handle){ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileLookupAndGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileLookupAndGetRequest.java index f3d09b398..f42ff4f94 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileLookupAndGetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileLookupAndGetRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileLookupRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileLookupRequest.java index c1e14dcd1..02facf09c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileLookupRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileLookupRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -28,6 +28,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSuppo import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; 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_hr.file.ResultCode; public class FileLookupRequest extends FossilRequest { private short handle = -1; @@ -81,8 +82,9 @@ public class FileLookupRequest extends FossilRequest { byte status = buffer.get(3); - if(status != 0){ - throw new RuntimeException("file lookup error: " + status); + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()){ + throw new RuntimeException("file lookup error: " + code + " (" + status + ")"); } if(this.handle != handle){ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FilePutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FilePutRequest.java index aeeaaf09f..1b95b01a7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FilePutRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FilePutRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Andreas Shimokawa, Daniel Dakhno This file is part of Gadgetbridge. @@ -27,6 +27,7 @@ import java.util.zip.CRC32; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.ResultCode; import nodomain.freeyourgadget.gadgetbridge.util.CRC32C; public class FilePutRequest extends FossilRequest { @@ -99,8 +100,9 @@ public class FilePutRequest extends FossilRequest { int crc = buffer.getInt(8); byte status = value[3]; - if (status != 0) { - throw new RuntimeException("upload status: " + status); + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()){ + throw new RuntimeException("upload status: " + code + " (" + status + ")"); } if (handle != this.handle) { @@ -144,9 +146,10 @@ public class FilePutRequest extends FossilRequest { byte status = buffer.get(3); - if (status != 0) { + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()){ onFilePut(false); - throw new RuntimeException("wrong closing status: " + status); + throw new RuntimeException("wrong closing status: " + code + " (" + status + ")"); } this.state = UploadState.UPLOADED; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileVerifyRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileVerifyRequest.java index 2f4cc032f..317d3fb4c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileVerifyRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/file/FileVerifyRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -22,6 +22,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.ResultCode; public class FileVerifyRequest extends FossilRequest { private boolean isFinished = false; @@ -64,7 +65,8 @@ public class FileVerifyRequest extends FossilRequest { byte status = buffer.get(3); - if(status != 0) throw new RuntimeException("wrong response status"); + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()) throw new RuntimeException("wrong response status: " + code + " (" + status + ")"); this.isFinished = true; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/microapp/MicroAppCommand.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/microapp/MicroAppCommand.java index df48b676e..9213b821e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/microapp/MicroAppCommand.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/microapp/MicroAppCommand.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/microapp/PlayCrazyShitRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/microapp/PlayCrazyShitRequest.java index 5028cc1e1..20de3fab2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/microapp/PlayCrazyShitRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/microapp/PlayCrazyShitRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterGetRequest.java index f22d70d27..8f4459a0e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterGetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterGetRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Andreas Shimokawa, Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterPutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterPutRequest.java index 0514d4aad..51d1ba953 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterPutRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/NotificationFilterPutRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -74,11 +74,12 @@ public class NotificationFilterPutRequest extends FilePutRequest { } enum PacketID{ - PACKAGE_NAME((byte) 1), - SENDER_NAME((byte) 2), - PACKAGE_NAME_CRC((byte) 4), - GROUP_ID((byte) 128), - APP_DISPLAY_NAME((byte) 129), + PACKAGE_NAME((byte) 0x01), + SENDER_NAME((byte) 0x02), + PACKAGE_NAME_CRC((byte) 0x04), + GROUP_ID((byte) 0x80), + APP_DISPLAY_NAME((byte) 0x81), + ICON((byte) 0x82), PRIORITY((byte) 0xC1), MOVEMENT((byte) 0xC2), VIBRATION((byte) 0xC3); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayCallNotificationRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayCallNotificationRequest.java new file mode 100644 index 000000000..52dda71be --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayCallNotificationRequest.java @@ -0,0 +1,14 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; + +public class PlayCallNotificationRequest extends PlayNotificationRequest { + public PlayCallNotificationRequest(String number, boolean callStart, FossilWatchAdapter adapter) { + super(callStart ? 1 : 7, callStart ? 8 : 2, + ByteBuffer.wrap(new byte[]{(byte) 0x80, (byte) 0x00, (byte) 0x59, (byte) 0xB7}).order(ByteOrder.LITTLE_ENDIAN).getInt(), + number, "Incoming Call", adapter); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayNotificationRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayNotificationRequest.java index b6f973594..977c6e0d2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayNotificationRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayNotificationRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -23,87 +23,63 @@ import java.util.zip.CRC32; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; +import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; -public class PlayNotificationRequest extends FilePutRequest { - - public PlayNotificationRequest(String packageName, FossilWatchAdapter adapter) { - // super((short) 0x0900, createFile("org.telegram.messenger", "org.telegram.messenger", "org.telegram.messenger"), adapter); - super((short) 0x0900, createFile(packageName), adapter); +public abstract class PlayNotificationRequest extends FilePutRequest { + public PlayNotificationRequest(int notificationType, int flags, String packageName, FossilWatchAdapter adapter) { + super((short) 0x0900, createFile(notificationType, flags, packageName, packageName, packageName), adapter); } - private static byte[] createFile(String packageName){ + public PlayNotificationRequest(int notificationType, int flags, String packageName, String sender, String message, FossilWatchAdapter adapter) { + super((short) 0x0900, createFile(notificationType, flags, packageName, sender, message), adapter); + } + + public PlayNotificationRequest(int notificationType, int flags, int packageCRC, String sender, String message, FossilWatchAdapter adapter) { + super((short) 0x0900, createFile(notificationType, flags, "whatever", sender, message, packageCRC), adapter); + } + + private static byte[] createFile(int notificationType, int flags, String packageName, String sender, String message){ CRC32 crc = new CRC32(); crc.update(packageName.getBytes()); - return createFile(packageName, packageName, packageName, (int)crc.getValue()); + return createFile(notificationType, flags, packageName, sender, message, (int)crc.getValue()); } - private static byte[] createFile(String title, String sender, String message, int packageCrc) { - // return new byte[]{(byte) 0x57, (byte) 0x00, (byte) 0x0A, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x17, (byte) 0x17, (byte) 0x17, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x49, (byte) 0x7B, (byte) 0x3B, (byte) 0x62, (byte) 0x6F, (byte) 0x72, (byte) 0x67, (byte) 0x2E, (byte) 0x74, (byte) 0x65, (byte) 0x6C, (byte) 0x65, (byte) 0x67, (byte) 0x72, (byte) 0x61, (byte) 0x6D, (byte) 0x2E, (byte) 0x6D, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x65, (byte) 0x6E, (byte) 0x67, (byte) 0x65, (byte) 0x72, (byte) 0x00, (byte) 0x6F, (byte) 0x72, (byte) 0x67, (byte) 0x2E, (byte) 0x74, (byte) 0x65, (byte) 0x6C, (byte) 0x65, (byte) 0x67, (byte) 0x72, (byte) 0x61, (byte) 0x6D, (byte) 0x2E, (byte) 0x6D, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x65, (byte) 0x6E, (byte) 0x67, (byte) 0x65, (byte) 0x72, (byte) 0x00, (byte) 0x6F, (byte) 0x72, (byte) 0x67, (byte) 0x2E, (byte) 0x74, (byte) 0x65, (byte) 0x6C, (byte) 0x65, (byte) 0x67, (byte) 0x72, (byte) 0x61, (byte) 0x6D, (byte) 0x2E, (byte) 0x6D, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x65, (byte) 0x6E, (byte) 0x67, (byte) 0x65, (byte) 0x72, (byte) 0x00}; - // gwb.k(var6, "ByteBuffer.allocate(10)"); + private static byte[] createFile(int notificationType, int flags, String title, String sender, String message, int packageCrc) { byte lengthBufferLength = (byte) 10; - byte typeId = 3; - byte flags = getFlags(); byte uidLength = (byte) 4; byte appBundleCRCLength = (byte) 4; - String nullTerminatedTitle = terminateNull(title); Charset charsetUTF8 = Charset.forName("UTF-8"); + + String nullTerminatedTitle = StringUtils.terminateNull(title); byte[] titleBytes = nullTerminatedTitle.getBytes(charsetUTF8); - // gwb.k(var13, "(this as java.lang.String).getBytes(charset)"); - String nullTerminatedSender = terminateNull(sender); + String nullTerminatedSender = StringUtils.terminateNull(sender); byte[] senderBytes = nullTerminatedSender.getBytes(charsetUTF8); - // gwb.k(var15, "(this as java.lang.String).getBytes(charset)"); - String nullTerminatedMessage = terminateNull(message); + String nullTerminatedMessage = StringUtils.terminateNull(message); byte[] messageBytes = nullTerminatedMessage.getBytes(charsetUTF8); - // gwb.k(var17, "(this as java.lang.String).getBytes(charset)"); short mainBufferLength = (short) (lengthBufferLength + uidLength + appBundleCRCLength + titleBytes.length + senderBytes.length + messageBytes.length); - ByteBuffer lengthBuffer = ByteBuffer.allocate(lengthBufferLength); - lengthBuffer.order(ByteOrder.LITTLE_ENDIAN); - lengthBuffer.putShort(mainBufferLength); - lengthBuffer.put(lengthBufferLength); - lengthBuffer.put(typeId); - lengthBuffer.put(flags); - lengthBuffer.put(uidLength); - lengthBuffer.put(appBundleCRCLength); - lengthBuffer.put((byte) titleBytes.length); - lengthBuffer.put((byte) senderBytes.length); - lengthBuffer.put((byte) messageBytes.length); - ByteBuffer mainBuffer = ByteBuffer.allocate(mainBufferLength); - // gwb.k(var11, "ByteBuffer.allocate(totalLen.toInt())"); mainBuffer.order(ByteOrder.LITTLE_ENDIAN); - mainBuffer.put(lengthBuffer.array()); - lengthBuffer = ByteBuffer.allocate(mainBufferLength - lengthBufferLength); - // gwb.k(var6, "ByteBuffer.allocate(totalLen - headerLen)"); - lengthBuffer.order(ByteOrder.LITTLE_ENDIAN); - lengthBuffer.putInt(0); - lengthBuffer.putInt(packageCrc); - lengthBuffer.put(titleBytes); - lengthBuffer.put(senderBytes); - lengthBuffer.put(messageBytes); - mainBuffer.put(lengthBuffer.array()); + mainBuffer.putShort(mainBufferLength); + + mainBuffer.put(lengthBufferLength); + mainBuffer.put((byte) notificationType); + mainBuffer.put((byte) flags); + mainBuffer.put(uidLength); + mainBuffer.put(appBundleCRCLength); + mainBuffer.put((byte) titleBytes.length); + mainBuffer.put((byte) senderBytes.length); + mainBuffer.put((byte) messageBytes.length); + + mainBuffer.putInt(0); // messageId + mainBuffer.putInt(packageCrc); + mainBuffer.put(titleBytes); + mainBuffer.put(senderBytes); + mainBuffer.put(messageBytes); return mainBuffer.array(); } - private static byte getFlags(){ - return (byte) 2; - } - - public static String terminateNull(String input){ - if(input.length() == 0){ - return new String(new byte[]{(byte) 0}); - } - char lastChar = input.charAt(input.length() - 1); - if(lastChar == 0) return input; - - byte[] newArray = new byte[input.length() + 1]; - System.arraycopy(input.getBytes(), 0, newArray, 0, input.length()); - - newArray[newArray.length - 1] = 0; - - return new String(newArray); - } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayTextNotificationRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayTextNotificationRequest.java new file mode 100644 index 000000000..b2a4a19b9 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayTextNotificationRequest.java @@ -0,0 +1,13 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; + +public class PlayTextNotificationRequest extends PlayNotificationRequest { + public PlayTextNotificationRequest(String packageName, String sender, String message, FossilWatchAdapter adapter) { + super(3, 2, packageName, sender, message, adapter); + } + + public PlayTextNotificationRequest(String packageName, FossilWatchAdapter adapter) { + super(3, 2, packageName, adapter); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/authentication/VerifyPrivateKeyRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/authentication/VerifyPrivateKeyRequest.java new file mode 100644 index 000000000..b6d491b17 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/authentication/VerifyPrivateKeyRequest.java @@ -0,0 +1,120 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication; + +import android.bluetooth.BluetoothGattCharacteristic; + +import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Random; +import java.util.UUID; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.ResultCode; + +public class VerifyPrivateKeyRequest extends FossilRequest { + private final FossilHRWatchAdapter adapter; + private byte[] key, randomPhoneNumber; + private boolean isFinished = false; + + public VerifyPrivateKeyRequest(byte[] key, FossilHRWatchAdapter adapter) { + this.adapter = adapter; + this.key = key; + + } + + @Override + public void handleResponse(BluetoothGattCharacteristic characteristic) { + super.handleResponse(characteristic); + byte[] value = characteristic.getValue(); + + ByteBuffer buffer = ByteBuffer.wrap(value); + + if (value[1] == 1) { + try { + byte[] bytesToDecrypt = new byte[16]; + + buffer.position(4); + + buffer.get(bytesToDecrypt, 0, 16); + + SecretKeySpec keySpec = new SecretKeySpec(this.key, "AES"); + Cipher cipher = null; + cipher = Cipher.getInstance("AES/CBC/NoPadding"); + cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})); + byte[] result = cipher.doFinal(bytesToDecrypt); + + byte[] bytesToEncrypt = new byte[16]; + + System.arraycopy(result, 0, bytesToEncrypt, 8, 8); + System.arraycopy(result, 8, bytesToEncrypt, 0, 8); + + byte[] watchRandomNumber = new byte[8]; + System.arraycopy(result, 0, watchRandomNumber, 0, 8); + + adapter.setWatchRandomNumber(watchRandomNumber); + adapter.setPhoneRandomNumber(randomPhoneNumber); + + cipher = Cipher.getInstance("AES/CBC/NoPadding"); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})); + result = cipher.doFinal(bytesToEncrypt); + + byte[] payload = new byte[19]; + payload[0] = 2; + payload[1] = 2; + payload[2] = 1; + + System.arraycopy(result, 0, payload, 3, 16); + + new TransactionBuilder("send encrypted random numbers") + .write(characteristic, payload) + .queue(this.adapter.getDeviceSupport().getQueue()); + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) { + throw new RuntimeException(e); + } + } else if (value[1] == 2) { + ResultCode code = ResultCode.fromCode(value[2]); + + if (!code.inidicatesSuccess()) throw new RuntimeException("Authentication error: " + code + " (" + value[2] + ")"); + + + this.isFinished = true; + } + } + + @Override + public boolean isFinished() { + return isFinished; + } + + @Override + public byte[] getStartSequence() { + ByteBuffer buffer = ByteBuffer.allocate(11); + + buffer.put((byte) 0x02); + buffer.put((byte) 0x01); + buffer.put((byte) 0x01); + + this.randomPhoneNumber = new byte[8]; + + new Random().nextBytes(randomPhoneNumber); + + buffer.put(randomPhoneNumber); + + return buffer.array(); + } + + @Override + public UUID getRequestUUID() { + return UUID.fromString("3dda0005-957f-7d4a-34a6-74696673696d"); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/buttons/ButtonConfigurationPutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/buttons/ButtonConfigurationPutRequest.java new file mode 100644 index 000000000..ebea27b27 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/buttons/ButtonConfigurationPutRequest.java @@ -0,0 +1,47 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons; + +import android.widget.Toast; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.json.JsonPutRequest; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public class ButtonConfigurationPutRequest extends JsonPutRequest { + public ButtonConfigurationPutRequest(String[] menuItems, FossilHRWatchAdapter adapter) { + super(createObject(menuItems), adapter); + } + + private static JSONObject createObject(String[] menuItems) { + try { + return new JSONObject() + .put("push", new JSONObject() + .put("set", new JSONObject() + .put("commuteApp._.config.destinations", new JSONArray(menuItems)) + .put("master._.config.buttons", new JSONArray() + .put(new JSONObject() + .put("name", "weatherApp") + .put("button_evt", "top_short_press_release") + ) + .put(new JSONObject() + .put("name", "commuteApp") + .put("button_evt", "middle_short_press_release") + ) + .put(new JSONObject() + .put("name", "commuteApp") + .put("button_evt", "bottom_short_press_release") + ) + ) + ) + ); + } catch (JSONException e) { + GB.toast("error creating json", Toast.LENGTH_LONG, GB.ERROR, e); + } + + return null; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/configuration/ConfigurationGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/configuration/ConfigurationGetRequest.java new file mode 100644 index 000000000..d5015f064 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/configuration/ConfigurationGetRequest.java @@ -0,0 +1,57 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration; + +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; +import nodomain.freeyourgadget.gadgetbridge.model.GenericItem; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedLookupAndGetRequest; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public class ConfigurationGetRequest extends FileEncryptedLookupAndGetRequest { + public ConfigurationGetRequest(FossilHRWatchAdapter adapter) { + super((byte) 0x08, adapter); + } + + @Override + public 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(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()))); + }else if(item instanceof ConfigurationPutRequest.TimezoneOffsetConfigItem) { + device.addDeviceInfo(new GenericItem(QHybridSupport.ITEM_TIMEZONE_OFFSET, String.valueOf(((ConfigurationPutRequest.TimezoneOffsetConfigItem) item).getValue()))); + }else if(item instanceof ConfigurationPutRequest.BatteryConfigItem){ + device.setBatteryLevel((short) ((ConfigurationPutRequest.BatteryConfigItem) item).getBatteryPercentage()); + device.setBatteryVoltage(((ConfigurationPutRequest.BatteryConfigItem) item).getBatteryVoltage() / 1000f); + device.setBatteryThresholdPercent((short) 15); + + GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo(); + batteryInfo.level = (short) ((ConfigurationPutRequest.BatteryConfigItem) item).getBatteryPercentage(); + batteryInfo.state = BatteryState.BATTERY_NORMAL; + getAdapter().getDeviceSupport().handleGBDeviceEvent(batteryInfo); + }else if(item instanceof ConfigurationPutRequest.HeartRateMeasurementModeItem){ + device.addDeviceInfo(new GenericItem(QHybridSupport.ITEM_HEART_RATE_MEASUREMENT_MODE, String.valueOf(((ConfigurationPutRequest.HeartRateMeasurementModeItem) item).getValue()))); + } + } + + GB.toast("got config", 0, GB.INFO); + + device.sendDeviceUpdateIntent(getAdapter().getContext()); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/configuration/ConfigurationPutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/configuration/ConfigurationPutRequest.java new file mode 100644 index 000000000..2c4f06c76 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/configuration/ConfigurationPutRequest.java @@ -0,0 +1,56 @@ +/* Copyright (C) 2019 Daniel Dakhno + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration; + +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; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedPutRequest; +import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.ConfigItem; + +public class ConfigurationPutRequest extends FileEncryptedPutRequest { + public ConfigurationPutRequest(ConfigItem item, FossilHRWatchAdapter adapter) { + super((short) 0x0800, createFileContent(new ConfigItem[]{item}), adapter); + } + + public ConfigurationPutRequest(ConfigItem[] items, FossilHRWatchAdapter adapter) { + super((short) 0x0800, createFileContent(items), adapter); + } + + private static byte[] createFileContent(ConfigItem[] items) { + int overallSize = items.length * 3; + for(ConfigItem item : items){ + overallSize += item.getItemSize(); + } + ByteBuffer buffer = ByteBuffer.allocate(overallSize); + buffer.order(ByteOrder.LITTLE_ENDIAN); + for(ConfigItem item : items){ + buffer.putShort(item.getId()); + buffer.put((byte) item.getItemSize()); + buffer.put(item.getContent()); + } + + return buffer.array(); + } +} + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/AssetFile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/AssetFile.java new file mode 100644 index 000000000..bf23584b9 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/AssetFile.java @@ -0,0 +1,42 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file; + +import java.nio.ByteBuffer; +import java.util.zip.CRC32; + +import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; + + +public class AssetFile { + private String fileName; + private byte[] fileData; + + protected AssetFile(String fileName, byte[] fileData) { + this.fileName = fileName; + this.fileData = fileData; + } + + public AssetFile(byte[] fileData) { + CRC32 crc = new CRC32(); + crc.update(fileData); + + this.fileName = StringUtils.bytesToHex( + ByteBuffer.allocate(4) + .putInt((int) crc.getValue()) + .array() + ); + + this.fileData = fileData; + } + + public String getFileName() { + return fileName; + } + + public byte[] getFileData() { + return fileData; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/AssetFilePutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/AssetFilePutRequest.java new file mode 100644 index 000000000..e6709d971 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/AssetFilePutRequest.java @@ -0,0 +1,44 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; + +public class AssetFilePutRequest extends FilePutRequest { + public AssetFilePutRequest(AssetFile[] files, byte subHandle, FossilWatchAdapter adapter) throws IOException { + super((short) (0x0700 | subHandle), prepareFileData(files), adapter); + } + public AssetFilePutRequest(AssetFile file, byte subHandle, FossilWatchAdapter adapter) throws IOException { + super((short) (0x0700 | subHandle), prepareFileData(file), adapter); + } + + private static byte[] prepareFileData(AssetFile[] files) throws IOException { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + + for(int i = 0; i < files.length; i++){ + stream.write( + prepareFileData(files[i]) + ); + } + + return stream.toByteArray(); + } + + private static byte[] prepareFileData(AssetFile file){ + int size = file.getFileName().length() + file.getFileData().length + 1 /**null byte **/; + ByteBuffer buffer = ByteBuffer.allocate(size + 2); + + buffer.order(ByteOrder.LITTLE_ENDIAN); + + buffer.putShort((short)(size)); + buffer.put(file.getFileName().getBytes()); + buffer.put((byte) 0x00); + buffer.put(file.getFileData()); + + return buffer.array(); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FileEncryptedGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FileEncryptedGetRequest.java new file mode 100644 index 000000000..867bf49e3 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FileEncryptedGetRequest.java @@ -0,0 +1,166 @@ +/* Copyright (C) 2019 Daniel Dakhno + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file; + +import android.bluetooth.BluetoothGattCharacteristic; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.UUID; +import java.util.zip.CRC32; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +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_hr.FossilHRWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest; + +public abstract class FileEncryptedGetRequest extends FossilRequest { + private short handle; + private FossilHRWatchAdapter adapter; + + private ByteBuffer fileBuffer; + + private byte[] fileData; + + private boolean finished = false; + + public FileEncryptedGetRequest(short handle, FossilHRWatchAdapter adapter) { + this.handle = handle; + this.adapter = adapter; + + this.data = + createBuffer() + .putShort(handle) + .putInt(0) + .putInt(0xFFFFFFFF) + .array(); + } + + public FossilWatchAdapter getAdapter() { + return adapter; + } + + @Override + public boolean isFinished(){ + return finished; + } + + @Override + public void handleResponse(BluetoothGattCharacteristic characteristic) { + byte[] value = characteristic.getValue(); + byte first = value[0]; + if(characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")){ + if((first & 0x0F) == 1){ + ByteBuffer buffer = ByteBuffer.wrap(value); + buffer.order(ByteOrder.LITTLE_ENDIAN); + + short handle = buffer.getShort(1); + int size = buffer.getInt(4); + + byte status = buffer.get(3); + + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()){ + throw new RuntimeException("FileGet error: " + code + " (" + status + ")"); + } + + if(this.handle != handle){ + throw new RuntimeException("handle: " + handle + " expected: " + this.handle); + } + log("file size: " + size); + fileBuffer = ByteBuffer.allocate(size); + }else if((first & 0x0F) == 8){ + this.finished = true; + + ByteBuffer buffer = ByteBuffer.wrap(value); + buffer.order(ByteOrder.LITTLE_ENDIAN); + + short handle = buffer.getShort(1); + if(this.handle != handle){ + throw new RuntimeException("handle: " + handle + " expected: " + this.handle); + } + + CRC32 crc = new CRC32(); + crc.update(this.fileData); + + int crcExpected = buffer.getInt(8); + + if((int) crc.getValue() != crcExpected){ + throw new RuntimeException("crc: " + crc.getValue() + " expected: " + crcExpected); + } + + this.handleFileData(this.fileData); + } + }else if(characteristic.getUuid().toString().equals("3dda0004-957f-7d4a-34a6-74696673696d")){ + SecretKeySpec keySpec = new SecretKeySpec(this.adapter.getSecretKey(), "AES"); + try { + Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); + + byte[] fileIV = new byte[16]; + + + byte[] phoneRandomNumber = adapter.getPhoneRandomNumber(); + byte[] watchRandomNumber = adapter.getWatchRandomNumber(); + + System.arraycopy(phoneRandomNumber, 0, fileIV, 2, 6); + System.arraycopy(watchRandomNumber, 0, fileIV, 9, 7); + + fileIV[7]++; + + cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(fileIV)); + + byte[] result = cipher.doFinal(value); + + fileBuffer.put(result, 1, result.length - 1); + if((result[0] & 0x80) == 0x80){ + this.fileData = fileBuffer.array(); + } + } catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + throw new RuntimeException(e); + } + } + } + + @Override + public UUID getRequestUUID() { + return UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d"); + } + + @Override + public byte[] getStartSequence() { + return new byte[]{1}; + } + + @Override + public int getPayloadLength() { + return 11; + } + + abstract public void handleFileData(byte[] fileData); +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FileEncryptedLookupAndGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FileEncryptedLookupAndGetRequest.java new file mode 100644 index 000000000..a5d64d988 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FileEncryptedLookupAndGetRequest.java @@ -0,0 +1,40 @@ +/* Copyright (C) 2019 Daniel Dakhno + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileLookupRequest; + +public abstract class FileEncryptedLookupAndGetRequest extends FileLookupRequest { + public FileEncryptedLookupAndGetRequest(byte fileType, FossilHRWatchAdapter adapter) { + super(fileType, adapter); + } + + @Override + public void handleFileLookup(short fileHandle){ + getAdapter().queueWrite(new FileEncryptedGetRequest(getHandle(), (FossilHRWatchAdapter) getAdapter()) { + @Override + public void handleFileData(byte[] fileData) { + FileEncryptedLookupAndGetRequest.this.handleFileData(fileData); + } + }, true); + } + + abstract public void handleFileData(byte[] fileData); +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FileEncryptedPutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FileEncryptedPutRequest.java new file mode 100644 index 000000000..d10ece07f --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FileEncryptedPutRequest.java @@ -0,0 +1,273 @@ +/* Copyright (C) 2019 Daniel Dakhno + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file; + +import android.bluetooth.BluetoothGattCharacteristic; +import android.widget.Toast; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.UUID; +import java.util.zip.CRC32; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest; +import nodomain.freeyourgadget.gadgetbridge.util.CRC32C; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public class FileEncryptedPutRequest extends FossilRequest { + public enum UploadState {INITIALIZED, UPLOADING, CLOSING, UPLOADED} + + public UploadState state; + + private ArrayList packets = new ArrayList<>(); + + private short handle; + + private FossilHRWatchAdapter adapter; + + private byte[] file; + + private int fullCRC; + + public FileEncryptedPutRequest(short handle, byte[] file, FossilHRWatchAdapter adapter) { + this.handle = handle; + this.adapter = adapter; + + int fileLength = file.length + 16; + ByteBuffer buffer = this.createBuffer(); + buffer.putShort(1, handle); + buffer.putInt(3, 0); + buffer.putInt(7, fileLength); + buffer.putInt(11, fileLength); + + this.data = buffer.array(); + + this.file = file; + + state = UploadState.INITIALIZED; + } + + public short getHandle() { + return handle; + } + + @Override + public void handleResponse(BluetoothGattCharacteristic characteristic) { + byte[] value = characteristic.getValue(); + if (characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")) { + int responseType = value[0] & 0x0F; + log("response: " + responseType); + switch (responseType) { + case 3: { + if (value.length != 5 || (value[0] & 0x0F) != 3) { + throw new RuntimeException("wrong answer header"); + } + state = UploadState.UPLOADING; + + TransactionBuilder transactionBuilder = new TransactionBuilder("file upload"); + BluetoothGattCharacteristic uploadCharacteristic = adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0004-957f-7d4a-34a6-74696673696d")); + + this.prepareFilePackets(this.file); + + SecretKeySpec keySpec = new SecretKeySpec(this.adapter.getSecretKey(), "AES"); + try { + Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); + + byte[] fileIV = new byte[16]; + + + byte[] phoneRandomNumber = adapter.getPhoneRandomNumber(); + byte[] watchRandomNumber = adapter.getWatchRandomNumber(); + + System.arraycopy(phoneRandomNumber, 0, fileIV, 2, 6); + System.arraycopy(watchRandomNumber, 0, fileIV, 9, 7); + + fileIV[7]++; + + cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(fileIV)); + + for (byte[] packet : packets) { + byte[] result = cipher.doFinal(packet); + transactionBuilder.write(uploadCharacteristic, result); + } + }catch (Exception e){ + GB.toast("error encrypting file", Toast.LENGTH_LONG, GB.ERROR, e); + } + + transactionBuilder.queue(adapter.getDeviceSupport().getQueue()); + break; + } + case 8: { + if (value.length == 4) return; + ByteBuffer buffer = ByteBuffer.wrap(value); + buffer.order(ByteOrder.LITTLE_ENDIAN); + short handle = buffer.getShort(1); + int crc = buffer.getInt(8); + byte status = value[3]; + + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()){ + throw new RuntimeException("upload status: " + code + " (" + status + ")"); + } + + if (handle != this.handle) { + throw new RuntimeException("wrong response handle"); + } + + if (crc != this.fullCRC) { + throw new RuntimeException("file upload exception: wrong crc"); + } + + + ByteBuffer buffer2 = ByteBuffer.allocate(3); + buffer2.order(ByteOrder.LITTLE_ENDIAN); + buffer2.put((byte) 4); + buffer2.putShort(this.handle); + + new TransactionBuilder("file close") + .write( + adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d")), + buffer2.array() + ) + .queue(adapter.getDeviceSupport().getQueue()); + + this.state = UploadState.CLOSING; + break; + } + case 4: { + if (value.length == 9) return; + if (value.length != 4 || (value[0] & 0x0F) != 4) { + throw new RuntimeException("wrong file closing header"); + } + ByteBuffer buffer = ByteBuffer.wrap(value); + buffer.order(ByteOrder.LITTLE_ENDIAN); + + short handle = buffer.getShort(1); + + if (handle != this.handle) { + onFilePut(false); + throw new RuntimeException("wrong file closing handle"); + } + + byte status = buffer.get(3); + + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()){ + onFilePut(false); + throw new RuntimeException("wrong closing status: " + code + " (" + status + ")"); + } + + this.state = UploadState.UPLOADED; + + onFilePut(true); + + log("uploaded file"); + + break; + } + case 9: { + this.onFilePut(false); + throw new RuntimeException("file put timeout"); + /*timeout = true; + ByteBuffer buffer2 = ByteBuffer.allocate(3); + buffer2.order(ByteOrder.LITTLE_ENDIAN); + buffer2.put((byte) 4); + buffer2.putShort(this.handle); + + new TransactionBuilder("file close") + .write( + adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d")), + buffer2.array() + ) + .queue(adapter.getDeviceSupport().getQueue()); + + this.state = UploadState.CLOSING; + break;*/ + } + } + } + } + + @Override + public boolean isFinished() { + return this.state == UploadState.UPLOADED; + } + + private void prepareFilePackets(byte[] file) { + int maxPacketSize = adapter.getMTU() - 4; + + ByteBuffer buffer = ByteBuffer.allocate(file.length + 12 + 4); + buffer.order(ByteOrder.LITTLE_ENDIAN); + + buffer.putShort(handle); + buffer.put((byte) 2); + buffer.put((byte) 0); + buffer.putInt(0); + buffer.putInt(file.length); + + buffer.put(file); + + CRC32C crc = new CRC32C(); + + crc.update(file,0,file.length); + buffer.putInt((int) crc.getValue()); + + byte[] data = buffer.array(); + + CRC32 fullCRC = new CRC32(); + + fullCRC.update(data); + this.fullCRC = (int) fullCRC.getValue(); + + int packetCount = (int) Math.ceil(data.length / (float) maxPacketSize); + + for (int i = 0; i < packetCount; i++) { + int currentPacketLength = Math.min(maxPacketSize, data.length - i * maxPacketSize); + byte[] packet = new byte[currentPacketLength + 1]; + packet[0] = (byte) i; + System.arraycopy(data, i * maxPacketSize, packet, 1, currentPacketLength); + + packets.add(packet); + } + } + + public void onFilePut(boolean success) { + } + + @Override + public byte[] getStartSequence() { + return new byte[]{0x03}; + } + + @Override + public int getPayloadLength() { + return 15; + } + + @Override + public UUID getRequestUUID() { + return UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d"); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FilePutRawRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FilePutRawRequest.java new file mode 100644 index 000000000..4091acd67 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/FilePutRawRequest.java @@ -0,0 +1,216 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file; + +import android.bluetooth.BluetoothGattCharacteristic; +import android.widget.Toast; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.UUID; +import java.util.zip.CRC32; + +import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEQueue; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public class FilePutRawRequest extends FossilRequest { + public enum UploadState {INITIALIZED, UPLOADING, CLOSING, UPLOADED} + + public UploadState state; + + public ArrayList packets = new ArrayList<>(); + + private short handle; + + private FossilWatchAdapter adapter; + + byte[] file; + + int fullCRC; + + public FilePutRawRequest(short handle, byte[] file, FossilWatchAdapter adapter) { + this.handle = handle; + this.adapter = adapter; + + int fileLength = file.length; + ByteBuffer buffer = this.createBuffer(); + buffer.putShort(1, handle); + buffer.putInt(3, 0); + buffer.putInt(7, fileLength); + buffer.putInt(11, fileLength); + + this.data = buffer.array(); + + this.file = file; + + state = UploadState.INITIALIZED; + } + + public short getHandle() { + return handle; + } + + @Override + public void handleResponse(BluetoothGattCharacteristic characteristic) { + byte[] value = characteristic.getValue(); + if (characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")) { + int responseType = value[0] & 0x0F; + log("response: " + responseType); + switch (responseType) { + case 3: { + if (value.length != 5 || (value[0] & 0x0F) != 3) { + throw new RuntimeException("wrong answer header"); + } + state = UploadState.UPLOADING; + + TransactionBuilder transactionBuilder = new TransactionBuilder("file upload"); + BluetoothGattCharacteristic uploadCharacteristic = adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0004-957f-7d4a-34a6-74696673696d")); + + this.prepareFilePackets(this.file); + + for (byte[] packet : packets) { + transactionBuilder.write(uploadCharacteristic, packet); + } + + transactionBuilder.queue(adapter.getDeviceSupport().getQueue()); + break; + } + case 8: { + if (value.length == 4) return; + ByteBuffer buffer = ByteBuffer.wrap(value); + buffer.order(ByteOrder.LITTLE_ENDIAN); + short handle = buffer.getShort(1); + int crc = buffer.getInt(8); + byte status = value[3]; + + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()){ + throw new RuntimeException("upload status: " + code + " (" + status + ")"); + } + + if (handle != this.handle) { + throw new RuntimeException("wrong response handle"); + } + + if (crc != this.fullCRC) { + throw new RuntimeException("file upload exception: wrong crc"); + } + + + ByteBuffer buffer2 = ByteBuffer.allocate(3); + buffer2.order(ByteOrder.LITTLE_ENDIAN); + buffer2.put((byte) 4); + buffer2.putShort(this.handle); + + new TransactionBuilder("file close") + .write( + adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d")), + buffer2.array() + ) + .queue(adapter.getDeviceSupport().getQueue()); + + this.state = UploadState.CLOSING; + break; + } + case 4: { + if (value.length == 9) return; + if (value.length != 4 || (value[0] & 0x0F) != 4) { + throw new RuntimeException("wrong file closing header"); + } + ByteBuffer buffer = ByteBuffer.wrap(value); + buffer.order(ByteOrder.LITTLE_ENDIAN); + + short handle = buffer.getShort(1); + + if (handle != this.handle) { + onFilePut(false); + throw new RuntimeException("wrong file closing handle"); + } + + byte status = buffer.get(3); + + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()){ + onFilePut(false); + throw new RuntimeException("wrong closing status: " + code + " (" + status + ")"); + } + + this.state = UploadState.UPLOADED; + + onFilePut(true); + + log("uploaded file"); + + break; + } + case 9: { + this.onFilePut(false); + throw new RuntimeException("file put timeout"); + /*timeout = true; + ByteBuffer buffer2 = ByteBuffer.allocate(3); + buffer2.order(ByteOrder.LITTLE_ENDIAN); + buffer2.put((byte) 4); + buffer2.putShort(this.handle); + + new TransactionBuilder("file close") + .write( + adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d")), + buffer2.array() + ) + .queue(adapter.getDeviceSupport().getQueue()); + + this.state = UploadState.CLOSING; + break;*/ + } + } + } + } + + @Override + public boolean isFinished() { + return this.state == UploadState.UPLOADED; + } + + private void prepareFilePackets(byte[] file) { + int maxPacketSize = adapter.getMTU() - 4; + + byte[] data = file; + + CRC32 fullCRC = new CRC32(); + + fullCRC.update(data); + this.fullCRC = (int) fullCRC.getValue(); + + int packetCount = (int) Math.ceil(data.length / (float) maxPacketSize); + + for (int i = 0; i < packetCount; i++) { + int currentPacketLength = Math.min(maxPacketSize, data.length - i * maxPacketSize); + byte[] packet = new byte[currentPacketLength + 1]; + packet[0] = (byte) i; + System.arraycopy(data, i * maxPacketSize, packet, 1, currentPacketLength); + + packets.add(packet); + } + } + + public void onFilePut(boolean success) { + } + + @Override + public byte[] getStartSequence() { + return new byte[]{0x03}; + } + + @Override + public int getPayloadLength() { + return 15; + } + + @Override + public UUID getRequestUUID() { + return UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d"); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/ResultCode.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/ResultCode.java new file mode 100644 index 000000000..ffee89d5d --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/ResultCode.java @@ -0,0 +1,56 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file; + +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public enum ResultCode { + SUCCESS(0, true), + INVALID_OPERATION_DATA(1, false), + OPERATION_IN_PROGRESS(2, false), + MISS_PACKET(3, false), + SOCKET_BUSY(4, false), + VERIFICATION_FAIL(5, false), + OVERFLOW(6, false), + SIZE_OVER_LIMIT(7, false), + FIRMWARE_INTERNAL_ERROR(128, false), + FIRMWARE_INTERNAL_ERROR_NOT_OPEN(129, false), + FIRMWARE_INTERNAL_ERROR_ACCESS_ERROR(130, false), + FIRMWARE_INTERNAL_ERROR_NOT_FOUND(131, false), + FIRMWARE_INTERNAL_ERROR_NOT_VALID(132, false), + FIRMWARE_INTERNAL_ERROR_ALREADY_CREATE(133, false), + FIRMWARE_INTERNAL_ERROR_NOT_ENOUGH_MEMORY(134, false), + FIRMWARE_INTERNAL_ERROR_NOT_IMPLEMENTED(135, false), + FIRMWARE_INTERNAL_ERROR_NOT_SUPPORT(136, false), + FIRMWARE_INTERNAL_ERROR_SOCKET_BUSY(137, false), + FIRMWARE_INTERNAL_ERROR_SOCKET_ALREADY_OPEN(138, false), + FIRMWARE_INTERNAL_ERROR_INPUT_DATA_INVALID(139, false), + FIRMWARE_INTERNAL_NOT_AUTHENTICATE(140, false), + FIRMWARE_INTERNAL_SIZE_OVER_LIMIT(141, false), + UNKNOWN(-1, false), + + // no clue what there one mean + UNKNOWN_1(-125, true); + + boolean success; + int code; + + private ResultCode(int code, boolean success){ + this.code = code; + this.success = success; + } + + public boolean inidicatesSuccess(){ + return this.success; + } + + public static ResultCode fromCode(int code){ + for (ResultCode resultCode : ResultCode.values()){ + if(resultCode.code == code) { + if(resultCode == UNKNOWN_1){ + GB.log("dunno what code this is: " + code, GB.INFO, null); + } + return resultCode; + } + } + return UNKNOWN; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/AssetImage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/AssetImage.java new file mode 100644 index 000000000..4c33a686f --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/AssetImage.java @@ -0,0 +1,67 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image; + +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFile; + +public class AssetImage extends AssetFile { + private int angle, distance, indexZ; + + protected AssetImage(byte[] fileData, int angle, int distance, int indexZ) { + super(fileData); + this.angle = angle; + this.distance = distance; + this.indexZ = indexZ; + } + + @NonNull + @Override + public String toString() { + return toJsonObject().toString(); + } + + public JSONObject toJsonObject(){ + try { + return new JSONObject() + .put("image_name", getFileName()) + .put("pos", + new JSONObject() + .put("angle", angle) + .put("distance", distance) + .put("z_index", indexZ) + ); + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } + + public int getAngle() { + return angle; + } + + public void setAngle(int angle) { + this.angle = angle; + } + + public int getDistance() { + return distance; + } + + public void setDistance(int distance) { + this.distance = distance; + } + + public int getIndexZ() { + return indexZ; + } + + public void setIndexZ(int indexZ) { + this.indexZ = indexZ; + } + + +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/AssetImageFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/AssetImageFactory.java new file mode 100644 index 000000000..0426ef3ac --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/AssetImageFactory.java @@ -0,0 +1,72 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.ColorSpace; + +import androidx.annotation.ColorInt; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +public class AssetImageFactory { + public static AssetImage createAssetImage(byte[] fileData, int angle, int distance, int indexZ){ + return new AssetImage(fileData, angle, distance, indexZ); + } + + public static AssetImage createAssetImage(Bitmap fileData, boolean RLEencode, int angle, int distance, int indexZ) throws IOException { + if(RLEencode){ + int height = fileData.getHeight(); + int width = fileData.getWidth(); + + // if(fileData.getConfig() != Bitmap.Config.ALPHA_8) throw new RuntimeException("Bitmap is not ALPHA_8"); + + int[] pixels = new int[height * width]; + + fileData.getPixels(pixels, 0, width, 0, 0, width, height); + + byte[] pixelBytes = new byte[width * height]; + + for(int i = 0; i < pixels.length; i++){ + int monochrome = convertToMonochrome(pixels[i]); + monochrome >>= 6; + + int alpha = Color.alpha(pixels[i]); + monochrome |= (~((alpha & 0xFF) >> 4) & 0b00001100); + + pixelBytes[i] = (byte) monochrome; + } + return new AssetImage(ImageConverter.encodeToRLEImage(pixelBytes, height, width), angle, distance, indexZ); + }else{ + // applies only to big background + int width = 240; + int height = 240; + + byte[] pixelBytes = new byte[width * height]; + + float jumpX = fileData.getWidth() / (float) width; + float jumpY = fileData.getHeight() / (float) height; + for(int y = 0; y < height; y++){ + for(int x = 0; x < width; x++){ + int pixel = fileData.getPixel((int)(x * jumpX), (int)(y * jumpY)); + + int monochrome = convertToMonochrome(pixel); + + pixelBytes[pixelBytes.length - 1 - (y * width + x)] = (byte) monochrome; + } + } + + return new AssetImage(ImageConverter.encodeToRawImage(pixelBytes), angle, distance, indexZ); + } + } + + private static @ColorInt int convertToMonochrome(@ColorInt int color){ + int sum = Color.red(color) + Color.green(color) + Color.blue(color); + + sum /= 3; + + return sum; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImageConverter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImageConverter.java new file mode 100644 index 000000000..09559d49a --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImageConverter.java @@ -0,0 +1,44 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image; + +import android.graphics.Bitmap; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.encoder.RLEEncoder; + +public class ImageConverter { + public static void encodeToTwoBitImage(byte monochromeImage){ + + } + + public static byte[] encodeToRLEImage(byte[] monochromeImage, int height, int width) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(monochromeImage.length * 2); + + bos.write((byte) height); + bos.write((byte) width); + + bos.write(RLEEncoder.RLEEncode(monochromeImage)); + + bos.write((byte) 0x0FF); + bos.write((byte) 0x0FF); + + return bos.toByteArray(); + } + + public static byte[] encodeToRawImage(byte[] monochromeImage){ + int imageSize = monochromeImage.length; + + byte[] result = new byte[imageSize / 4]; // 4 pixels per byte e.g. 2 bits per pixel + + for(int i = 0; i < imageSize; i++){ + int resultPixelIndex = i / 4; + int shiftIndex = 6 - i % 4 * 2; + + result[resultPixelIndex] |= (byte) (((monochromeImage[i] & 0xFF) >> 6) << shiftIndex); + assert Boolean.TRUE; + } + + return result; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImagesSetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImagesSetRequest.java new file mode 100644 index 000000000..bf854b85c --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/image/ImagesSetRequest.java @@ -0,0 +1,35 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.json.JsonPutRequest; + +public class ImagesSetRequest extends JsonPutRequest { + public ImagesSetRequest(AssetImage[] images, FossilHRWatchAdapter adapter) { + super(prepareObject(images), adapter); + } + + private static JSONObject prepareObject(AssetImage[] images){ + try { + JSONArray imageArray = new JSONArray(); + for (AssetImage image : images) imageArray.put(image.toJsonObject()); + return new JSONObject() + .put("push", + new JSONObject() + .put("set", + new JSONObject() + .put("watchFace._.config.backgrounds", + imageArray + ) + ) + ); + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/json/JsonPutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/json/JsonPutRequest.java new file mode 100644 index 000000000..bd2c9237a --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/json/JsonPutRequest.java @@ -0,0 +1,14 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.json; + +import org.json.JSONObject; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FilePutRawRequest; + +public class JsonPutRequest extends FilePutRawRequest { + public JsonPutRequest(JSONObject object, FossilHRWatchAdapter adapter) { + super((short)(0x0500 | (adapter.getJsonIndex() & 0xFF)), object.toString().getBytes(), adapter); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/menu/SetCommuteMenuMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/menu/SetCommuteMenuMessage.java new file mode 100644 index 000000000..8c6533eac --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/menu/SetCommuteMenuMessage.java @@ -0,0 +1,31 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.menu; + +import org.json.JSONException; +import org.json.JSONObject; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.json.JsonPutRequest; + +public class SetCommuteMenuMessage extends JsonPutRequest { + public SetCommuteMenuMessage(String message, boolean finished, FossilHRWatchAdapter adapter) { + super(createObject(message, finished), adapter); + } + + private static JSONObject createObject(String message, boolean finished) { + try { + return new JSONObject() + .put("push", new JSONObject() + .put("set", new JSONObject() + .put("commuteApp._.config.commute_info", new JSONObject() + .put("message", message) + .put("type", finished ? "end" : "in_progress") + ) + ) + ); + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/music/MusicControlRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/music/MusicControlRequest.java new file mode 100644 index 000000000..64930fec5 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/music/MusicControlRequest.java @@ -0,0 +1,76 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music; + +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest; + +public class MusicControlRequest extends FossilRequest { + private MUSIC_PHONE_REQUEST request; + + public MusicControlRequest(MUSIC_PHONE_REQUEST request) { + this.request = request; + + this.data = new byte[]{ + (byte) 0x02, + (byte) 0x05, + this.request.getCommandByte(), + (byte) 0x00 + }; + } + + @Override + public boolean isFinished() { + return true; + } + + @Override + public byte[] getStartSequence() { + return null; + } + + @Override + public UUID getRequestUUID() { + return UUID.fromString("3dda0006-957f-7d4a-34a6-74696673696d"); + } + + public enum MUSIC_WATCH_REQUEST { + MUSIC_REQUEST_PLAY_PAUSE((byte) 0x02), + MUSIC_REQUEST_NEXT((byte) 0x03), + MUSIC_REQUEST_PREVIOUS((byte) 0x04), + MUSIC_REQUEST_LOUDER((byte) 0x05), + MUSIC_REQUEST_QUITER((byte) 0x06), + ; + private byte commandByte; + + MUSIC_WATCH_REQUEST(byte commandByte) { + this.commandByte = commandByte; + } + + public static MUSIC_WATCH_REQUEST fromCommandByte(byte commandByte){ + for(MUSIC_WATCH_REQUEST request : MUSIC_WATCH_REQUEST.values()){ + if(request.commandByte == commandByte) return request; + } + return null; + } + } + + public enum MUSIC_PHONE_REQUEST { + MUSIC_REQUEST_SET_PLAYING((byte) 0x00), + MUSIC_REQUEST_SET_PAUSED((byte) 0x01), + MUSIC_REQUEST_PLAY_PAUSE((byte) 0x02), + MUSIC_REQUEST_NEXT((byte) 0x03), + MUSIC_REQUEST_PREVIOUS((byte) 0x04), + MUSIC_REQUEST_LOUDER((byte) 0x05), + MUSIC_REQUEST_QUITER((byte) 0x06), + ; + private byte commandByte; + + public byte getCommandByte() { + return commandByte; + } + + private MUSIC_PHONE_REQUEST(byte commandByte) { + this.commandByte = commandByte; + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/music/MusicInfoSetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/music/MusicInfoSetRequest.java new file mode 100644 index 000000000..6546cbc37 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/music/MusicInfoSetRequest.java @@ -0,0 +1,46 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music; + +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; + +public class MusicInfoSetRequest extends FilePutRequest { + public MusicInfoSetRequest(String artist, String album, String title, FossilWatchAdapter adapter) { + super((short) 0x0400, createFile(artist, album, title), adapter); + } + + private static byte[] createFile(String artist, String album, String title) { + //counting byte array length because of utf chars, they may take up two bytes + int titleLength = title.getBytes().length + 1; // +1 = null terminator + int albumLength = album.getBytes().length + 1; + int artistLength = artist.getBytes().length + 1; + + int length = artistLength + albumLength + titleLength + + 8; // length and header + + ByteBuffer buffer = ByteBuffer.allocate(length); + buffer.order(ByteOrder.LITTLE_ENDIAN); + + buffer.putShort((short) length); + buffer.put((byte) 0x01); // dunno + buffer.put((byte) (titleLength)); + buffer.put((byte) (artistLength)); + buffer.put((byte) (albumLength)); + buffer.put((byte) 0x0C); // dunno + buffer.put((byte) 0x00); // dunno + + buffer.put(title.getBytes()) + .put((byte) 0x00); // null terminator + + buffer.put(artist.getBytes()) + .put((byte) 0x00); // null terminator + + buffer.put(album.getBytes()) + .put((byte) 0x00); // null terminator + + return buffer.array(); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationFilterPutHRRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationFilterPutHRRequest.java new file mode 100644 index 000000000..1d6cacb12 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationFilterPutHRRequest.java @@ -0,0 +1,94 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; + +import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationHRConfiguration; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; +import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; + +public class NotificationFilterPutHRRequest extends FilePutRequest { + public NotificationFilterPutHRRequest(NotificationHRConfiguration[] configs, FossilWatchAdapter adapter) { + super((short) 0x0C00, createFile(configs), adapter); + } + + + public NotificationFilterPutHRRequest(ArrayList configs, FossilWatchAdapter adapter) { + super((short) 0x0C00, createFile(configs.toArray(new NotificationHRConfiguration[0])), adapter); + } + + private static byte[] createFile(NotificationHRConfiguration[] configs) { + int payloadLength = configs.length * 28; + ByteBuffer buffer = ByteBuffer.allocate(payloadLength); + buffer.order(ByteOrder.LITTLE_ENDIAN); + + for (NotificationHRConfiguration config : configs) { + payloadLength = 26; + + buffer.putShort((short) payloadLength); //packet length + + byte[] crcBytes = config.getPackageCrc(); + + // 6 bytes + buffer.put(PacketID.PACKAGE_NAME_CRC.id) + .put((byte) 4) + .put(crcBytes); + + // 3 bytes + buffer.put(PacketID.GROUP_ID.id) + .put((byte) 1) + .put((byte) 0); + + // 3 bytes + buffer.put(PacketID.PRIORITY.id) + .put((byte) 1) + .put((byte) 0xFF); + + // 14 bytes + buffer.put(PacketID.ICON.id) + .put((byte) 0x0C) + .put((byte) 0xFF) + .put((byte) 0x00) + .put((byte) 0x09) + .put(StringUtils.bytesToHex(crcBytes).getBytes()) + .put((byte) 0x00); + + } + + return buffer.array(); + } + + enum PacketID { + PACKAGE_NAME((byte) 0x01), + SENDER_NAME((byte) 0x02), + PACKAGE_NAME_CRC((byte) 0x04), + GROUP_ID((byte) 0x80), + APP_DISPLAY_NAME((byte) 0x81), + ICON((byte) 0x82), + 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; + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationImage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationImage.java new file mode 100644 index 000000000..98626fea2 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationImage.java @@ -0,0 +1,23 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFile; + +public class NotificationImage extends AssetFile { + private String packageName; + private byte[] imageData; + + public NotificationImage(String packageName, byte[] imageData) { + //TODO this is defo not functional + super(packageName, imageData); + this.packageName = packageName; + this.imageData = imageData; + } + + public String getPackageName() { + return packageName; + } + + public byte[] getImageData() { + return imageData; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationImagePutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationImagePutRequest.java new file mode 100644 index 000000000..27850f7f1 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/notification/NotificationImagePutRequest.java @@ -0,0 +1,53 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.zip.CRC32; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFile; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFilePutRequest; +import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; + +public class NotificationImagePutRequest extends AssetFilePutRequest { + private NotificationImagePutRequest(String packageName, AssetFile file, FossilWatchAdapter adapter) throws IOException { + super(file, (byte) 0x01, adapter); + } + + private NotificationImagePutRequest(NotificationImage image, FossilWatchAdapter adapter) throws IOException { + super(image, (byte) 0x01, adapter); + } + + public NotificationImagePutRequest(NotificationImage[] images, FossilWatchAdapter adapter) throws IOException { + super(images, (byte) 0x01, adapter); + } + + + private static byte[][] prepareFileCrc(String[] packageNames){ + byte[][] names = new byte[packageNames.length][]; + for (int i = 0; i < packageNames.length; i++){ + names[i] = prepareFileCrc(packageNames[i]); + } + return names; + } + + private static byte[] prepareFileCrc(String packageName){ + CRC32 crc = new CRC32(); + crc.update(packageName.getBytes()); + + String crcString = StringUtils.bytesToHex( + ByteBuffer + .allocate(4) + .order(ByteOrder.LITTLE_ENDIAN) + .putInt((int) crc.getValue()) + .array() + ); + + ByteBuffer buffer = ByteBuffer.allocate(crcString.length() + 1) + .put(crcString.getBytes()) + .put((byte) 0x00); + + return buffer.array(); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomBackgroundWidgetElement.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomBackgroundWidgetElement.java new file mode 100644 index 000000000..5e16e6cfc --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomBackgroundWidgetElement.java @@ -0,0 +1,11 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget; + +public class CustomBackgroundWidgetElement extends CustomWidgetElement{ + public CustomBackgroundWidgetElement(String id, String value) { + super(WidgetElementType.TYPE_BACKGROUND, id, value, 0, 0); + } + + public CustomBackgroundWidgetElement(String value) { + super(WidgetElementType.TYPE_BACKGROUND, null, value, 0, 0); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomTextWidgetElement.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomTextWidgetElement.java new file mode 100644 index 000000000..367220aae --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomTextWidgetElement.java @@ -0,0 +1,11 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget; + +public class CustomTextWidgetElement extends CustomWidgetElement{ + public CustomTextWidgetElement(String id, String value, int x, int y) { + super(WidgetElementType.TYPE_TEXT, id, value, x, y); + } + + public CustomTextWidgetElement(String value, int x, int y) { + super(WidgetElementType.TYPE_TEXT, null, value, x, y); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomWidget.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomWidget.java new file mode 100644 index 000000000..d6f1f0af3 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomWidget.java @@ -0,0 +1,75 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; + +public class CustomWidget extends Widget { + private ArrayList elements = new ArrayList<>(); + private int angle, distance; + private String name; + + public CustomWidget(String name, int angle, int distance, String fontColor) { + super(null, angle, distance, fontColor); + this.angle = angle; + this.distance = distance; + this.name = name; + } + + public int getAngle() { + return angle; + } + + public int getDistance() { + return distance; + } + + public void setElements(ArrayList elements) { + this.elements = elements; + } + + public void setAngle(int angle) { + this.angle = angle; + } + + public void setDistance(int distance) { + this.distance = distance; + } + + public void setName(String name) { + this.name = name; + } + + public ArrayList getElements(){ + return this.elements; + } + + public void addElement(CustomWidgetElement element){ + this.elements.add(element); + } + + public boolean updateElementValue(String id, String value){ + boolean updatedValue = false; + for(CustomWidgetElement element : this.elements){ + String elementId = element.getId(); + if(elementId != null && elementId.equals(id)){ + element.setValue(value); + updatedValue = true; + } + } + return updatedValue; + } + + private CustomWidgetElement getElement(String id){ + for(CustomWidgetElement element : this.elements){ + String elementId = element.getId(); + if(elementId != null && elementId.equals(id)) return element; + } + return null; + } + + public String getName() { + return name; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomWidgetElement.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomWidgetElement.java new file mode 100644 index 000000000..dfaded275 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/CustomWidgetElement.java @@ -0,0 +1,92 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget; + +import java.io.Serializable; + +import nodomain.freeyourgadget.gadgetbridge.R; + +public class CustomWidgetElement implements Serializable { + public enum WidgetElementType { + TYPE_TEXT(R.id.qhybrid_widget_elements_type_text, "text"), + TYPE_IMAGE(0, "image"), + TYPE_BACKGROUND(R.id.qhybrid_widget_elements_type_background, "background"); + + private String jsonIdentifier; + private int radioButtonResource; + + WidgetElementType(int radioButtonResource, String jsonIdentifier){ + this.radioButtonResource = radioButtonResource; + this.jsonIdentifier = jsonIdentifier; + } + + public int getRadioButtonResource() { + return radioButtonResource; + } + + public String getJsonIdentifier() { + return jsonIdentifier; + } + + static public WidgetElementType fromRadioButtonRessource(int radioButtonResource){ + for(WidgetElementType type : values()){ + if(type.getRadioButtonResource() == radioButtonResource) return type; + } + return null; + } + } + + public final static int X_CENTER = 38; + public final static int Y_UPPER_HALF = (int) (76f / 3 * 1); + public final static int Y_LOWER_HALF = (int) (76f / 3 * 2); + + private WidgetElementType widgetElementType; + private String id, value; + private int x, y; + + public void setWidgetElementType(WidgetElementType widgetElementType) { + this.widgetElementType = widgetElementType; + } + + public void setId(String id) { + this.id = id; + } + + public void setX(int x) { + this.x = x; + } + + public void setY(int y) { + this.y = y; + } + + protected CustomWidgetElement(WidgetElementType widgetElementType, String id, String value, int x, int y) { + this.widgetElementType = widgetElementType; + this.id = id; + this.value = value; + this.x = x; + this.y = y; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public WidgetElementType getWidgetElementType() { + return widgetElementType; + } + + public String getId() { + return id; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/Widget.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/Widget.java new file mode 100644 index 000000000..19de46906 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/Widget.java @@ -0,0 +1,87 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget; + +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.Serializable; + +import nodomain.freeyourgadget.gadgetbridge.R; + +public class Widget implements Serializable { + private WidgetType widgetType; + private int angle, distance; + private String fontColor; + + public Widget(WidgetType type, int angle, int distance, String fontColor) { + this.widgetType = type; + this.angle = angle; + this.distance = distance; + this.fontColor = fontColor; + } + + @NonNull + @Override + public String toString() { + return toJson().toString(); + } + + public JSONObject toJson() { + JSONObject object = new JSONObject(); + + try { + object + .put("name", widgetType.getIdentifier()) + .put("pos", + new JSONObject() + .put("angle", angle) + .put("distance", distance) + ) + .put("data", new JSONObject()) + .put("theme", + new JSONObject() + .put("font_color", fontColor) + ); + } catch (JSONException e) { + e.printStackTrace(); + } + + return object; + } + + + public enum WidgetType { + HEART_RATE("hrSSE", R.string.hr_widget_heart_rate), + STEPS("stepsSSE", R.string.hr_widget_steps), + DATE("dateSSE", R.string.hr_widget_date), + ACTIVE_MINUTES("activeMinutesSSE", R.string.hr_widget_active_minutes), + CALORIES("caloriesSSE", R.string.hr_widget_calories), + BATTERY("batterySSE", R.string.hr_widget_battery), + WEATHER("weatherSSE", R.string.hr_widget_weather), + NOTHING(null, R.string.hr_widget_nothing); + + private String identifier; + private int stringResource; + + WidgetType(String identifier, int stringResource) { + this.identifier = identifier; + this.stringResource = stringResource; + } + + public static WidgetType fromJsonIdentifier(String jsonIdentifier){ + for(WidgetType type : values()){ + if(type.getIdentifier() != null && type.getIdentifier().equals(jsonIdentifier)) return type; + } + return null; + } + + public int getStringResource() { + return stringResource; + } + + public String getIdentifier() { + return this.identifier; + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/WidgetsPutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/WidgetsPutRequest.java new file mode 100644 index 000000000..aecef97e0 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/widget/WidgetsPutRequest.java @@ -0,0 +1,41 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FilePutRawRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.json.JsonPutRequest; + +public class WidgetsPutRequest extends JsonPutRequest { + public WidgetsPutRequest(Widget[] widgets, FossilHRWatchAdapter adapter) { + super(prepareFile(widgets), adapter); + } + + private static JSONObject prepareFile(Widget[] widgets){ + try { + JSONArray widgetArray = new JSONArray(); + + for(Widget widget : widgets){ + widgetArray.put(widget.toJson()); + } + + JSONObject object = new JSONObject() + .put( + "push", + new JSONObject() + .put("set", + new JSONObject().put( + "watchFace._.config.comps", widgetArray + ) + ) + ); + return object; + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ActivityPointGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ActivityPointGetRequest.java index 85c45af60..148803fb3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ActivityPointGetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ActivityPointGetRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/AnimationRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/AnimationRequest.java index 96dd8aedb..5dcd0617a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/AnimationRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/AnimationRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/BatteryLevelRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/BatteryLevelRequest.java index 26b641b7a..267ea86b1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/BatteryLevelRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/BatteryLevelRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/DownloadFileRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/DownloadFileRequest.java index af6f78bb5..a51d6d606 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/DownloadFileRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/DownloadFileRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. @@ -22,6 +22,8 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.zip.CRC32; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.ResultCode; + public class DownloadFileRequest extends FileRequest { ByteBuffer buffer = null; public byte[] file = null; @@ -68,8 +70,9 @@ public class DownloadFileRequest extends FileRequest { buffer1.order(ByteOrder.LITTLE_ENDIAN); this.status = buffer1.get(3); short realHandle = buffer1.getShort(1); - if(status != 0){ - log("wrong status: " + status); + ResultCode code = ResultCode.fromCode(status); + if(!code.inidicatesSuccess()){ + log("wrong status: " + code + " (" + status + ")"); }else if(realHandle != fileHandle){ log("wrong handle: " + realHandle); completed = true; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EraseFileRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EraseFileRequest.java index d17f09437..0796df2e8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EraseFileRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EraseFileRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EventStreamRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EventStreamRequest.java index 203242e9d..9cf6ffa5a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EventStreamRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EventStreamRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/FileRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/FileRequest.java index 310093f6e..45c82809d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/FileRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/FileRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCountdownSettingsRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCountdownSettingsRequest.java index 46f0b27d5..fdb67e63d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCountdownSettingsRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCountdownSettingsRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCurrentStepCountRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCurrentStepCountRequest.java index d94dd44f3..703f1334f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCurrentStepCountRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCurrentStepCountRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetStepGoalRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetStepGoalRequest.java index 9df0e12f2..eee851ed0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetStepGoalRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetStepGoalRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetTripleTapEnabledRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetTripleTapEnabledRequest.java index 9cc82dd2e..aabdc19e4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetTripleTapEnabledRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetTripleTapEnabledRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetVibrationStrengthRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetVibrationStrengthRequest.java index 0ef4be5c7..8ce56c764 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetVibrationStrengthRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetVibrationStrengthRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GoalTrackingGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GoalTrackingGetRequest.java index 941e38d0d..be7758280 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GoalTrackingGetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GoalTrackingGetRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GoalTrackingSetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GoalTrackingSetRequest.java index 241f9987c..afc1360c1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GoalTrackingSetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GoalTrackingSetRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ListFilesRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ListFilesRequest.java index f6ebfbc34..4565270be 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ListFilesRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ListFilesRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/MoveHandsRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/MoveHandsRequest.java index 87924bbe1..0868da136 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/MoveHandsRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/MoveHandsRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAEnterRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAEnterRequest.java index 7d9de55dd..330bf726f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAEnterRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAEnterRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAEraseRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAEraseRequest.java index 986d8c828..b240ea38e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAEraseRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAEraseRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAResetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAResetRequest.java index 8cbaff5df..2d328857e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAResetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/OTAResetRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/PlayNotificationRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/PlayNotificationRequest.java index 3fc94a85f..cb7296581 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/PlayNotificationRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/PlayNotificationRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/PutSettingsFileRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/PutSettingsFileRequest.java index afba3a5c8..8718f16db 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/PutSettingsFileRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/PutSettingsFileRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ReleaseHandsControlRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ReleaseHandsControlRequest.java index 49fb24ef6..ef366630b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ReleaseHandsControlRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/ReleaseHandsControlRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/RequestHandControlRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/RequestHandControlRequest.java index 39b52aeb6..a782a3be0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/RequestHandControlRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/RequestHandControlRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCountdownSettings.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCountdownSettings.java index 0b3dd2c18..566a1940d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCountdownSettings.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCountdownSettings.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCurrentStepCountRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCurrentStepCountRequest.java index 481dfe446..04920bd32 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCurrentStepCountRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCurrentStepCountRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCurrentTimeServiceRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCurrentTimeServiceRequest.java index dd8f868e6..f863fb684 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCurrentTimeServiceRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetCurrentTimeServiceRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetStepGoalRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetStepGoalRequest.java index fac0a7ae0..6467ee141 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetStepGoalRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetStepGoalRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetTimeRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetTimeRequest.java index ffb5d2992..8d5cd3617 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetTimeRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetTimeRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetTripleTapEnabledRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetTripleTapEnabledRequest.java index a446894fd..1aef8b5be 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetTripleTapEnabledRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetTripleTapEnabledRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetVibrationStrengthRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetVibrationStrengthRequest.java index 197bd3e19..3ca8aeaba 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetVibrationStrengthRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SetVibrationStrengthRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SettingsFilePutRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SettingsFilePutRequest.java index 2a5509332..b4b68b0a3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SettingsFilePutRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/SettingsFilePutRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/UploadFileRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/UploadFileRequest.java index 005395d4c..0e83bdeea 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/UploadFileRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/UploadFileRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/VibrateRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/VibrateRequest.java index c21f53406..dd1a6c197 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/VibrateRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/VibrateRequest.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Daniel Dakhno +/* Copyright (C) 2019-2020 Daniel Dakhno This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi1Protocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi1Protocol.java index 43fb57044..53f4de056 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi1Protocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi1Protocol.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 José Rebelo +/* Copyright (C) 2018-2020 José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi3Protocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi3Protocol.java index ea047abbf..7d1092c86 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi3Protocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/Roidmi3Protocol.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 José Rebelo +/* Copyright (C) 2018-2020 José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiIoThread.java index ba11899b7..d950b2855 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiIoThread.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 José Rebelo +/* Copyright (C) 2018-2020 José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiProtocol.java index 340f9e6fb..bb283ad0c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiProtocol.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 José Rebelo +/* Copyright (C) 2018-2020 José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiSupport.java index 890c5c9a0..4b52f51fe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/roidmi/RoidmiSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 José Rebelo, Sebastian Kranz +/* Copyright (C) 2018-2020 José Rebelo, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java index 4cfa59a72..7ce90ea44 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Sebastian +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/watch9/Watch9DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/watch9/Watch9DeviceSupport.java index a99a07ad8..8bbd0bbba 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/watch9/Watch9DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/watch9/Watch9DeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2018-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, maxirnilian, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/watch9/operations/InitOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/watch9/operations/InitOperation.java index fa714ec43..e6acfbd0c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/watch9/operations/InitOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/watch9/operations/InitOperation.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 maxirnilian +/* Copyright (C) 2018-2020 maxirnilian This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xwatch/XWatchSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xwatch/XWatchSupport.java index 4800cd200..cc864d1cb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xwatch/XWatchSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xwatch/XWatchSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Andreas Shimokawa, Carsten Pfeiffer, ladbsoft, +/* Copyright (C) 2018-2020 Andreas Shimokawa, Carsten Pfeiffer, ladbsoft, Sebastian Kranz This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java index ae0352a84..2137d6c49 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/zetime/ZeTimeDeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 0nse, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer, Julien Pivotto, Kranz, Sebastian Kranz, Steffen Liebergeld This file is part of Gadgetbridge. @@ -67,6 +67,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; /** @@ -1682,7 +1683,9 @@ public class ZeTimeDeviceSupport extends AbstractBTLEDeviceSupport { } private void setTimeFormate(TransactionBuilder builder) { - String timeFormat = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()).getString(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, "24h"); + GBPrefs gbPrefs = new GBPrefs(new Prefs(GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()))); + + String timeFormat = gbPrefs.getTimeFormat(); int type = 1; if ("am/pm".equals(timeFormat)) { type = 2; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/AutoConnectIntervalReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/AutoConnectIntervalReceiver.java index b8540347c..4898343b4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/AutoConnectIntervalReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/AutoConnectIntervalReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa +/* Copyright (C) 2019-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBAutoFetchReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBAutoFetchReceiver.java index af5da58ce..049335666 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBAutoFetchReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBAutoFetchReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Daniele Gobbetti, Martin +/* Copyright (C) 2018-2020 Daniele Gobbetti, Martin This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java index b8e1daf70..e2bd99d4b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBCallControlReceiver.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. @@ -19,8 +19,12 @@ package nodomain.freeyourgadget.gadgetbridge.service.receivers; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.os.Build; +import android.telecom.TelecomManager; import android.telephony.TelephonyManager; +import androidx.annotation.RequiresApi; + import com.android.internal.telephony.ITelephony; import org.slf4j.Logger; @@ -28,35 +32,60 @@ import org.slf4j.LoggerFactory; import java.lang.reflect.Method; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; public class GBCallControlReceiver extends BroadcastReceiver { public static final String ACTION_CALLCONTROL = "nodomain.freeyourgadget.gadgetbridge.callcontrol"; private static final Logger LOG = LoggerFactory.getLogger(GBCallControlReceiver.class); + private Context mContext = GBApplication.getContext(); @Override public void onReceive(Context context, Intent intent) { GBDeviceEventCallControl.Event callCmd = GBDeviceEventCallControl.Event.values()[intent.getIntExtra("event", 0)]; - switch (callCmd) { - case END: - case REJECT: - case START: - try { - TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - Class clazz = Class.forName(telephonyManager.getClass().getName()); - Method method = clazz.getDeclaredMethod("getITelephony"); - method.setAccessible(true); - ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager); - if (callCmd == GBDeviceEventCallControl.Event.END || callCmd == GBDeviceEventCallControl.Event.REJECT) { - telephonyService.endCall(); - } else { - telephonyService.answerRingingCall(); + + if (GBApplication.isRunningPieOrLater()) { + handleCallCmdTelecomManager(callCmd); + } else { + switch (callCmd) { + case END: + case REJECT: + case START: + try { + TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + Class clazz = Class.forName(telephonyManager.getClass().getName()); + Method method = clazz.getDeclaredMethod("getITelephony"); + method.setAccessible(true); + ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager); + if (callCmd == GBDeviceEventCallControl.Event.END || callCmd == GBDeviceEventCallControl.Event.REJECT) { + telephonyService.endCall(); + } else { + telephonyService.answerRingingCall(); + } + } catch (Exception e) { + LOG.warn("could not start or hangup call"); } - } catch (Exception e) { - LOG.warn("could not start or hangup call"); - } - break; - default: + break; + default: + } + } + } + + @RequiresApi(api = Build.VERSION_CODES.P) + public void handleCallCmdTelecomManager(GBDeviceEventCallControl.Event callCmd) { + try { + TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); + + if (callCmd == GBDeviceEventCallControl.Event.END || callCmd == GBDeviceEventCallControl.Event.REJECT) { + tm.endCall(); + } else if (callCmd == GBDeviceEventCallControl.Event.START || callCmd == GBDeviceEventCallControl.Event.ACCEPT) { + tm.acceptRingingCall(); + } + + } catch (SecurityException e) { + LOG.warn("no permission to start or hangup call"); + } catch (Exception e) { + LOG.warn("could not start or hangup call"); } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBMusicControlReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBMusicControlReceiver.java index 54120ddf6..ed21dc5f1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBMusicControlReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBMusicControlReceiver.java @@ -1,5 +1,5 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele - Gobbetti, Gabe Schrecker +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti, Gabe Schrecker, vanous This file is part of Gadgetbridge. @@ -64,6 +64,12 @@ public class GBMusicControlReceiver extends BroadcastReceiver { case PLAYPAUSE: keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE; break; + case REWIND: + keyCode = KeyEvent.KEYCODE_MEDIA_REWIND; + break; + case FORWARD: + keyCode = KeyEvent.KEYCODE_MEDIA_FAST_FORWARD; + break; case VOLUMEUP: // change default and fall through, :P volumeAdjust = AudioManager.ADJUST_RAISE; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java index 53eff14ac..ba14cf31a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo, +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo, Julien Pivotto, Steffen Liebergeld This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceIoThread.java index b5a2ea28f..400c8c16d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceIoThread.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java index 69a33d7cb..d09c4b22a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo, +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo, Julien Pivotto, Steffen Liebergeld This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java index 22b9e9e8c..31c730016 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2019-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti This file is part of Gadgetbridge. @@ -47,8 +48,8 @@ public class AlarmUtils { * @param calendar * @return */ - public static nodomain.freeyourgadget.gadgetbridge.model.Alarm createSingleShot(int index, boolean smartWakeup, Calendar calendar) { - return new Alarm(-1, -1, index, true, smartWakeup, Alarm.ALARM_ONCE, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE)); + public static nodomain.freeyourgadget.gadgetbridge.model.Alarm createSingleShot(int index, boolean smartWakeup, boolean snooze, Calendar calendar) { + return new Alarm(-1, -1, index, true, smartWakeup, snooze, Alarm.ALARM_ONCE, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), false); } /** @@ -127,7 +128,7 @@ public class AlarmUtils { int hour = Integer.parseInt(tokens[4]); int minute = Integer.parseInt(tokens[5]); - return new Alarm(device.getId(), user.getId(), index, enabled, smartWakeup, repetition, hour, minute); + return new Alarm(device.getId(), user.getId(), index, enabled, smartWakeup, false, repetition, hour, minute, false); } private static Comparator createComparator() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AndroidUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AndroidUtils.java index a4b4ae49a..c411ce0e4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AndroidUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AndroidUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Felix Konstantin Maurer, Marc Nause, Taavi Eomäe, vanous This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ArrayUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ArrayUtils.java index b6cfa8101..d0c9470e3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ArrayUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ArrayUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BengaliLanguageUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BengaliLanguageUtils.java index 4007d8d52..4c4d37835 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BengaliLanguageUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BengaliLanguageUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Aniruddha Adhikary, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Aniruddha Adhikary, Carsten Pfeiffer, Daniele Gobbetti, Utsob Roy This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BitmapUtil.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BitmapUtil.java index 7f532291a..f3c1d1e93 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BitmapUtil.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BitmapUtil.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Frank Slezak +/* Copyright (C) 2017-2020 Frank Slezak This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java index 26b0b7a86..d4103e9bb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java index c234a4a39..44e693272 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, AndrewH, Carsten Pfeiffer, +/* Copyright (C) 2015-2020 Andreas Shimokawa, AndrewH, Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java index 5581844fb..922c5fb09 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java @@ -1,8 +1,8 @@ -/* Copyright (C) 2015-2019 0nse, Andreas Böhler, Andreas Shimokawa, +/* Copyright (C) 2015-2020 0nse, Andreas Böhler, Andreas Shimokawa, Carsten Pfeiffer, Cre3per, Daniel Dakhno, Daniele Gobbetti, Gordon Williams, Jean-François Greffier, João Paulo Barraca, José Rebelo, Kranz, ladbsoft, - Manuel Ruß, maxirnilian, protomors, Quallenauge, Sami Alaoui, Sophanimus, - tiparega, Vadim Kaushan + Manuel Ruß, maxirnilian, Pavel Elagin, protomors, Quallenauge, Sami Alaoui, + Sophanimus, tiparega, Vadim Kaushan This file is part of Gadgetbridge. @@ -50,6 +50,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.hplus.MakibesF68Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipLiteCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgtr.AmazfitGTRCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgts.AmazfitGTSCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.itag.ITagCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.makibeshr3.MakibesHR3Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.Q8Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipCoordinator; @@ -60,8 +61,9 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband2.MiBand2HRXCoor import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband3.MiBand3Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband4.MiBand4Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115Coordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.jyou.TeclastH30.TeclastH30Coordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.jyou.y5.Y5Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.jyou.BFH16DeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.jyou.TeclastH30Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.liveview.LiveviewCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; @@ -237,9 +239,11 @@ public class DeviceHelper { result.add(new WatchXPlusDeviceCoordinator()); result.add(new Roidmi1Coordinator()); result.add(new Roidmi3Coordinator()); + result.add(new Y5Coordinator()); result.add(new CasioGB6900DeviceCoordinator()); result.add(new BFH16DeviceCoordinator()); result.add(new MijiaLywsd02Coordinator()); + result.add(new ITagCoordinator()); result.add(new MakibesHR3Coordinator()); result.add(new BangleJSCoordinator()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/EmojiConverter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/EmojiConverter.java index 2968c71c3..650e41b8d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/EmojiConverter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/EmojiConverter.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Matthieu Baerts, Taavi Eomäe This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java index 035f7a9a8..9c2b7fbab 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Felix Konstantin Maurer, JohnnySun, Taavi Eomäe This file is part of Gadgetbridge. @@ -184,6 +184,25 @@ public class FileUtils { throw new IOException("no writable external directory found"); } + /** + * Returns a File object representing the "child" argument, but relative + * to the Android "external files directory" (e.g. /sdcard). + * It doesn't matter whether child shall represent a file or a directory. + * The parent directory will automatically be created, if necessary. + * @param child the path to become relative to the external files directory + * @throws IOException + * @see #getExternalFilesDir() + */ + public static File getExternalFile(String child) throws IOException { + File file = new File(getExternalFilesDir(), child); + File dir = file.getParentFile(); + if (!dir.exists() && !dir.mkdirs()) { + throw new IOException("Unable to create directory " + file.getParent()); + } + return file; + } + + private static boolean canWriteTo(File dir) { File file = new File(dir, "gbtest"); try { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java index 1c8238f68..f77f07964 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Felix Konstantin Maurer, Taavi Eomäe, Uwe Hermann, Yar This file is part of Gadgetbridge. @@ -59,6 +59,7 @@ import static nodomain.freeyourgadget.gadgetbridge.GBApplication.isRunningOreoOr public class GB { public static final String NOTIFICATION_CHANNEL_ID = "gadgetbridge"; + public static final String NOTIFICATION_CHANNEL_HIGH_PRIORITY_ID = "gadgetbridge_high_priority"; public static final String NOTIFICATION_CHANNEL_ID_TRANSFER = "gadgetbridge transfer"; public static final int NOTIFICATION_ID = 1; @@ -66,6 +67,7 @@ public class GB { public static final int NOTIFICATION_ID_LOW_BATTERY = 3; public static final int NOTIFICATION_ID_TRANSFER = 4; public static final int NOTIFICATION_ID_EXPORT_FAILED = 5; + public static final int NOTIFICATION_ID_PHONE_FIND = 6; private static final Logger LOG = LoggerFactory.getLogger(GB.class); public static final int INFO = 1; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java index 13b8867c5..716385866 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java @@ -1,5 +1,5 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Daniele Gobbetti, Dikay900, - Felix Konstantin Maurer +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti, Dikay900, Felix Konstantin Maurer This file is part of Gadgetbridge. @@ -17,9 +17,14 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.util; +import android.text.format.DateFormat; + import java.text.ParseException; import java.util.Date; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; + public class GBPrefs { public static final String PACKAGE_BLACKLIST = "package_blacklist"; public static final String PACKAGE_PEBBLEMSG_BLACKLIST = "package_pebblemsg_blacklist"; @@ -81,4 +86,17 @@ public class GBPrefs { public int getUserGender() { return 0; } + + public String getTimeFormat() { + String timeFormat = mPrefs.getString(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, "auto"); + if ("auto".equals(timeFormat)) { + if (DateFormat.is24HourFormat(GBApplication.getContext())) { + timeFormat = "24h"; + } else { + timeFormat = "am/pm"; + } + } + + return timeFormat; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ImportExportSharedPreferences.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ImportExportSharedPreferences.java index 3156eafb4..3c1227f67 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ImportExportSharedPreferences.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/ImportExportSharedPreferences.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Alberto, Andreas Shimokawa, Carsten Pfeiffer, +/* Copyright (C) 2017-2020 Alberto, Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Taavi Eomäe This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/JavaExtensions.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/JavaExtensions.java index 9411c1016..68a51508f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/JavaExtensions.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/JavaExtensions.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 ivanovlev +/* Copyright (C) 2017-2020 ivanovlev This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java index ef36d98b2..e6046f9cc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Aniruddha Adhikary, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Aniruddha Adhikary, Daniele Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, Ted Stein, Thomas, Yaron Shahrabani diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LimitedQueue.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LimitedQueue.java index d3e43a051..af71b977c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LimitedQueue.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LimitedQueue.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Daniel Dakhno, Daniele Gobbetti, +/* Copyright (C) 2015-2020 Andreas Shimokawa, Daniel Dakhno, Daniele Gobbetti, Julien Pivotto This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java index 4e26fed0d..cc697cc41 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Lukas Veneziano This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/PebbleUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/PebbleUtils.java index 3d9007c5c..daf51504f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/PebbleUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/PebbleUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Frank Slezak This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Prefs.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Prefs.java index 3dfd928bc..573d273ee 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Prefs.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Prefs.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, JohnnySun +/* Copyright (C) 2016-2020 Carsten Pfeiffer, JohnnySun This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/RtlUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/RtlUtils.java index e68cebc2c..3a282942e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/RtlUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/RtlUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2019 Andreas Shimokawa, Carsten Pfeiffer, Roi Greenberg +/* Copyright (C) 2018-2020 Andreas Shimokawa, Carsten Pfeiffer, Roi Greenberg This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java index 00a287f91..0495dae01 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, João Paulo Barraca, Nephiel, Roi Greenberg This file is part of Gadgetbridge. @@ -96,4 +96,23 @@ public class StringUtils { } return ""; } + + public static String terminateNull(String input) { + if (input == null || input.length() == 0) { + return new String(new byte[]{(byte) 0}); + } + char lastChar = input.charAt(input.length() - 1); + if (lastChar == 0) return input; + + byte[] newArray = new byte[input.getBytes().length + 1]; + System.arraycopy(input.getBytes(), 0, newArray, 0, input.getBytes().length); + + newArray[newArray.length - 1] = 0; + + return new String(newArray); + } + + public static String bytesToHex(byte[] array) { + return GB.hexdump(array, 0, -1); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java index 77c799bcb..97e1cc32a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Carsten Pfeiffer, José Rebelo +/* Copyright (C) 2017-2020 Carsten Pfeiffer, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/UriHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/UriHelper.java index 9dafe1163..095cb3d1f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/UriHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/UriHelper.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Carsten Pfeiffer, Daniele Gobbetti +/* Copyright (C) 2016-2020 Carsten Pfeiffer, Daniele Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java index d3ce720c9..baa1c1a9e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, Michal Novotny +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Michal Novotny This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/WebViewSingleton.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/WebViewSingleton.java index 64a1e8488..092a1489f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/WebViewSingleton.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/WebViewSingleton.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Lem Dulfo, Uwe Hermann This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/XTimePreference.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/XTimePreference.java index e1bebb771..6cfe3c806 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/XTimePreference.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/XTimePreference.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo +/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/XTimePreferenceFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/XTimePreferenceFragment.java index 005ee8be8..45755c94f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/XTimePreferenceFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/XTimePreferenceFragment.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Andreas Shimokawa +/* Copyright (C) 2019-2020 Andreas Shimokawa This file is part of Gadgetbridge. diff --git a/app/src/main/java/ru/gelin/android/weather/notification/ParcelableWeather2.java b/app/src/main/java/ru/gelin/android/weather/notification/ParcelableWeather2.java index 4c6f5f24c..bfe633b60 100644 --- a/app/src/main/java/ru/gelin/android/weather/notification/ParcelableWeather2.java +++ b/app/src/main/java/ru/gelin/android/weather/notification/ParcelableWeather2.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, Taavi Eomäe This file is part of Gadgetbridge. diff --git a/app/src/main/res/drawable-hdpi/ic_device_default.png b/app/src/main/res/drawable-hdpi/ic_device_default.png deleted file mode 100644 index 39682624c..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_default.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device_default_disabled.png b/app/src/main/res/drawable-hdpi/ic_device_default_disabled.png deleted file mode 100644 index 1bac776d6..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_default_disabled.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device_h30_h10.png b/app/src/main/res/drawable-hdpi/ic_device_h30_h10.png deleted file mode 100644 index 4a599d7b8..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_h30_h10.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device_h30_h10_disabled.png b/app/src/main/res/drawable-hdpi/ic_device_h30_h10_disabled.png deleted file mode 100644 index f3da742ca..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_h30_h10_disabled.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_default.png b/app/src/main/res/drawable-mdpi/ic_device_default.png deleted file mode 100644 index 77c6f1829..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_default.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_default_disabled.png b/app/src/main/res/drawable-mdpi/ic_device_default_disabled.png deleted file mode 100644 index 8e63a4de1..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_default_disabled.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_h30_h10.png b/app/src/main/res/drawable-mdpi/ic_device_h30_h10.png deleted file mode 100644 index 729cbd624..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_h30_h10.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_h30_h10_disabled.png b/app/src/main/res/drawable-mdpi/ic_device_h30_h10_disabled.png deleted file mode 100644 index 72840f433..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_h30_h10_disabled.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_default.png b/app/src/main/res/drawable-xhdpi/ic_device_default.png deleted file mode 100644 index 1b45d346c..000000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_default.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_default_disabled.png b/app/src/main/res/drawable-xhdpi/ic_device_default_disabled.png deleted file mode 100644 index f345ede52..000000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_default_disabled.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_h30_h10.png b/app/src/main/res/drawable-xhdpi/ic_device_h30_h10.png deleted file mode 100644 index 5ce9b58e4..000000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_h30_h10.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_h30_h10_disabled.png b/app/src/main/res/drawable-xhdpi/ic_device_h30_h10_disabled.png deleted file mode 100644 index a3a55f5c4..000000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_h30_h10_disabled.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_default.png b/app/src/main/res/drawable-xxhdpi/ic_device_default.png deleted file mode 100644 index 57c0aeabf..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_default.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_default_disabled.png b/app/src/main/res/drawable-xxhdpi/ic_device_default_disabled.png deleted file mode 100644 index 4289e81fa..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_default_disabled.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_h30_h10.png b/app/src/main/res/drawable-xxhdpi/ic_device_h30_h10.png deleted file mode 100644 index 08f72ddbe..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_h30_h10.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_h30_h10_disabled.png b/app/src/main/res/drawable-xxhdpi/ic_device_h30_h10_disabled.png deleted file mode 100644 index 2d1d4eff1..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_h30_h10_disabled.png and /dev/null differ diff --git a/app/src/main/res/drawable/ic_device_default.xml b/app/src/main/res/drawable/ic_device_default.xml new file mode 100644 index 000000000..6a019f7bd --- /dev/null +++ b/app/src/main/res/drawable/ic_device_default.xml @@ -0,0 +1,38 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_default_disabled.xml b/app/src/main/res/drawable/ic_device_default_disabled.xml new file mode 100644 index 000000000..b3a75ef29 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_default_disabled.xml @@ -0,0 +1,38 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_h30_h10.xml b/app/src/main/res/drawable/ic_device_h30_h10.xml new file mode 100644 index 000000000..7c7e79e28 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_h30_h10.xml @@ -0,0 +1,39 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_h30_h10_disabled.xml b/app/src/main/res/drawable/ic_device_h30_h10_disabled.xml new file mode 100644 index 000000000..0e2753a00 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_h30_h10_disabled.xml @@ -0,0 +1,39 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_itag.xml b/app/src/main/res/drawable/ic_device_itag.xml new file mode 100644 index 000000000..95e1a19c7 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_itag.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_itag_disabled.xml b/app/src/main/res/drawable/ic_device_itag_disabled.xml new file mode 100644 index 000000000..1acdba6e2 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_itag_disabled.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_miscale2.xml b/app/src/main/res/drawable/ic_device_miscale2.xml new file mode 100644 index 000000000..2eb436c25 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_miscale2.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_miscale2_disabled.xml b/app/src/main/res/drawable/ic_device_miscale2_disabled.xml new file mode 100644 index 000000000..a3e717402 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_miscale2_disabled.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_alarm_details.xml b/app/src/main/res/layout/activity_alarm_details.xml index 4610a3430..f3ab4f7dd 100644 --- a/app/src/main/res/layout/activity_alarm_details.xml +++ b/app/src/main/res/layout/activity_alarm_details.xml @@ -33,12 +33,22 @@ android:text="@string/alarm_smart_wakeup" android:textAppearance="?android:attr/textAppearanceSmall" /> + + + + + + +