├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── values │ │ │ │ ├── dimens.xml │ │ │ │ ├── arrays.xml │ │ │ │ ├── styles.xml │ │ │ │ ├── colors.xml │ │ │ │ └── attr.xml │ │ │ ├── layout │ │ │ │ ├── fragment_can_variables.xml │ │ │ │ ├── fragment_gps_satellites.xml │ │ │ │ ├── activity_settings.xml │ │ │ │ ├── fragment_can_data.xml │ │ │ │ ├── template_flow_master_detail.xml │ │ │ │ ├── fragment_gps_sentences.xml │ │ │ │ ├── fragment_device_list.xml │ │ │ │ ├── rule_list.xml │ │ │ │ ├── dialog_text.xml │ │ │ │ ├── action_property.xml │ │ │ │ ├── rule_list_content.xml │ │ │ │ ├── template_activity_master_detail.xml │ │ │ │ ├── activity_usb_status.xml │ │ │ │ ├── listitem_carduino_variable.xml │ │ │ │ ├── action_detail.xml │ │ │ │ ├── listitem_app_statistic.xml │ │ │ │ ├── overlay_bubble_car.xml │ │ │ │ └── rule_detail.xml │ │ │ ├── drawable │ │ │ │ ├── selector_bottom_navigation.xml │ │ │ │ ├── ic_menu_add.xml │ │ │ │ ├── ic_menu_ok.xml │ │ │ │ ├── ic_dashboard_stats_rules.xml │ │ │ │ ├── ic_cc_mode_face.xml │ │ │ │ ├── ic_cc_mode_ws.xml │ │ │ │ ├── ic_cc_mode_feet.xml │ │ │ │ ├── ic_action_device_disconnect.xml │ │ │ │ ├── ic_device_feature_events.xml │ │ │ │ ├── ic_cc_status_small_off.xml │ │ │ │ ├── ic_cc_status_small_on.xml │ │ │ │ ├── ic_overlay_close.xml │ │ │ │ ├── ic_pref_rules.xml │ │ │ │ ├── ic_dashboard_stats_vars.xml │ │ │ │ ├── ic_dashboard_stats_feature.xml │ │ │ │ ├── ic_tab_gps_raw.xml │ │ │ │ ├── ic_action_device_reset.xml │ │ │ │ ├── ic_action_device_reboot.xml │ │ │ │ ├── ic_pref_compatibility.xml │ │ │ │ ├── ic_pref_overlay.xml │ │ │ │ ├── ic_cc_fan.xml │ │ │ │ ├── ic_device_feature_location.xml │ │ │ │ ├── ic_cc_off.xml │ │ │ │ ├── ic_device_feature_errors.xml │ │ │ │ ├── ic_pref_gps.xml │ │ │ │ ├── ic_cc_recirculation.xml │ │ │ │ ├── ic_cc_status_off.xml │ │ │ │ ├── ic_cc_status_on.xml │ │ │ │ ├── seekarc_thumb.xml │ │ │ │ ├── ic_pref_devices.xml │ │ │ │ ├── ic_action_device_delete.xml │ │ │ │ ├── ic_cc_ac.xml │ │ │ │ ├── ic_dashboard_stats_devices.xml │ │ │ │ ├── ic_banner_permissions.xml │ │ │ │ ├── ic_device_type_unknown.xml │ │ │ │ ├── ic_device_feature_unknown.xml │ │ │ │ ├── ic_device_type_gps.xml │ │ │ │ ├── ic_tab_usb.xml │ │ │ │ ├── ic_pref_usb.xml │ │ │ │ ├── ic_tab_gps_status.xml │ │ │ │ ├── ic_pref_car.xml │ │ │ │ ├── ic_tab_car.xml │ │ │ │ ├── ic_device_feature_can.xml │ │ │ │ ├── ic_device_type_carduino.xml │ │ │ │ ├── ic_cc_mode_bg.xml │ │ │ │ ├── ic_cc_auto.xml │ │ │ │ ├── ic_dashboard_settings.xml │ │ │ │ ├── bg_dashboard_toolbar.xml │ │ │ │ ├── bg_dashboard_menu.xml │ │ │ │ ├── ic_cc_rwh.xml │ │ │ │ └── ic_cc_wsh.xml │ │ │ ├── menu │ │ │ │ ├── action_detail_menu.xml │ │ │ │ ├── rule_detail_menu.xml │ │ │ │ ├── dashboard_menu.xml │ │ │ │ ├── bottom_navigation_carduino_monitor.xml │ │ │ │ ├── bottom_navigation_gps_monitor.xml │ │ │ │ └── dashboard_actions.xml │ │ │ ├── xml │ │ │ │ ├── pref_compatibility.xml │ │ │ │ └── pref_main.xml │ │ │ └── layout-w900dp │ │ │ │ └── template_flow_master_detail.xml │ │ └── java │ │ │ └── de │ │ │ └── jlab │ │ │ └── cardroid │ │ │ ├── devices │ │ │ ├── serial │ │ │ │ ├── SerialConnectionListener.java │ │ │ │ ├── carduino │ │ │ │ │ ├── EventInteractable.java │ │ │ │ │ ├── EventObservable.java │ │ │ │ │ ├── CarduinoEventInteractable.java │ │ │ │ │ ├── CarduinoPacketParser.java │ │ │ │ │ ├── CarduinoMetaType.java │ │ │ │ │ ├── CarduinoEventType.java │ │ │ │ │ ├── CarduinoFeatureDetector.java │ │ │ │ │ ├── CarduinoEventParser.java │ │ │ │ │ ├── CarduinoErrorParser.java │ │ │ │ │ ├── CarduinoPacketType.java │ │ │ │ │ └── CarduinoCanParser.java │ │ │ │ ├── SerialPacket.java │ │ │ │ ├── gps │ │ │ │ │ ├── GpsSatellite.java │ │ │ │ │ ├── GpsSerialReader.java │ │ │ │ │ └── GpsPositionParser.java │ │ │ │ ├── BinarySerialPacket.java │ │ │ │ └── SerialReader.java │ │ │ ├── Feature.java │ │ │ ├── ObservableFeature.java │ │ │ ├── usb │ │ │ │ ├── UsbDevice.java │ │ │ │ └── serial │ │ │ │ │ ├── gps │ │ │ │ │ └── GpsUsbDevice.java │ │ │ │ │ └── carduino │ │ │ │ │ ├── KeepAlive.java │ │ │ │ │ └── CarduinoCanInteractable.java │ │ │ ├── ui │ │ │ │ ├── DeviceListViewModel.java │ │ │ │ └── DeviceDetailViewModel.java │ │ │ ├── storage │ │ │ │ ├── DeviceConverters.java │ │ │ │ ├── DeviceDao.java │ │ │ │ └── DeviceEntity.java │ │ │ ├── identification │ │ │ │ ├── DeviceConnectionId.java │ │ │ │ └── DeviceUid.java │ │ │ ├── DeviceDisconnectedReceiver.java │ │ │ ├── DeviceConnectionRequest.java │ │ │ ├── detection │ │ │ │ ├── UsbDeviceDetector.java │ │ │ │ ├── GpsSerialMatcher.java │ │ │ │ ├── CarduinoSerialMatcher.java │ │ │ │ └── UsbSerialDeviceDetector.java │ │ │ ├── DeviceType.java │ │ │ └── DeviceServiceConnection.java │ │ │ ├── errors │ │ │ ├── ErrorObservable.java │ │ │ ├── Error.java │ │ │ └── ErrorController.java │ │ │ ├── car │ │ │ ├── CanInteractable.java │ │ │ ├── CanObservable.java │ │ │ └── ui │ │ │ │ └── CarMonitorActivity.java │ │ │ ├── rules │ │ │ ├── Trigger.java │ │ │ ├── actions │ │ │ │ ├── AudioAction.java │ │ │ │ ├── VoiceAction.java │ │ │ │ ├── KillAppAction.java │ │ │ │ ├── StartAppAction.java │ │ │ │ ├── WifiToggleAction.java │ │ │ │ └── MediaKeyAction.java │ │ │ ├── storage │ │ │ │ ├── RuleDefinition.java │ │ │ │ ├── EventViewListModel.java │ │ │ │ ├── EventViewDetailModel.java │ │ │ │ ├── ActionDao.java │ │ │ │ ├── ActionViewDetailModel.java │ │ │ │ ├── EventDao.java │ │ │ │ ├── ActionEntity.java │ │ │ │ ├── EventEntity.java │ │ │ │ ├── ActionPropertyConverters.java │ │ │ │ ├── EventRepository.java │ │ │ │ └── ActionRepository.java │ │ │ ├── properties │ │ │ │ ├── Property.java │ │ │ │ ├── ActionPropertyEditor.java │ │ │ │ └── PropertyValue.java │ │ │ ├── KnownEvents.java │ │ │ ├── FragmentActionListener.java │ │ │ ├── Rule.java │ │ │ ├── Event.java │ │ │ └── ActionDefinition.java │ │ │ ├── gps │ │ │ ├── GpsObservable.java │ │ │ └── ui │ │ │ │ └── GpsMonitorActivity.java │ │ │ ├── utils │ │ │ ├── StopWatch.java │ │ │ ├── permissions │ │ │ │ ├── StandardPermission.java │ │ │ │ ├── OverlayPermission.java │ │ │ │ ├── PermissionRequest.java │ │ │ │ └── MockLocationPermission.java │ │ │ ├── ui │ │ │ │ ├── UnitValues.java │ │ │ │ ├── RoundCardView.java │ │ │ │ ├── DialogUtils.java │ │ │ │ └── FeatureActivity │ │ │ │ │ └── StatusGridAdapter.java │ │ │ ├── MultiMap.java │ │ │ └── UsageStatistics.java │ │ │ ├── overlay │ │ │ ├── SeekArcEvent.java │ │ │ ├── AbstractOverlayController.java │ │ │ └── OverlayToggleButton.java │ │ │ ├── variables │ │ │ ├── ObservableValue.java │ │ │ ├── ObservableValueBag.java │ │ │ ├── ScriptEngine.java │ │ │ └── Expression.java │ │ │ └── storage │ │ │ └── CardroidDatabase.java │ ├── test │ │ └── java │ │ │ └── de │ │ │ └── jlab │ │ │ └── cardroid │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── de │ │ └── jlab │ │ └── cardroid │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .idea ├── runConfigurations.xml └── gradle.xml ├── gradle.properties └── CHANGELOG.md /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rampage128/cardroid/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rampage128/cardroid/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rampage128/cardroid/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rampage128/cardroid/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rampage128/cardroid/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rampage128/cardroid/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rampage128/cardroid/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rampage128/cardroid/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rampage128/cardroid/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rampage128/cardroid/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rampage128/cardroid/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/serial/SerialConnectionListener.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.serial; 2 | 3 | public interface SerialConnectionListener { 4 | void onConnect(); 5 | void onDisconnect(); 6 | } 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Sep 25 16:57:20 CEST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 200dp 5 | 300dp 6 | 16dp 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/Feature.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices; 2 | 3 | public interface Feature { 4 | 5 | enum State { 6 | AVAILABLE, 7 | UNAVAILABLE 8 | } 9 | 10 | void setDevice(Device device); 11 | Device getDevice(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_can_variables.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/serial/carduino/EventInteractable.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.serial.carduino; 2 | 3 | import de.jlab.cardroid.devices.Feature; 4 | 5 | public interface EventInteractable extends Feature { 6 | 7 | void sendEvent(byte eventId, byte[] payload); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_bottom_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_gps_satellites.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_add.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_ok.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/serial/SerialPacket.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.serial; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | 6 | import androidx.annotation.NonNull; 7 | 8 | public interface SerialPacket { 9 | 10 | void serialize(@NonNull ByteArrayOutputStream stream) throws IOException; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dashboard_stats_rules.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_mode_face.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_mode_ws.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_mode_feet.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_action_device_disconnect.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_device_feature_events.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_status_small_off.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_status_small_on.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/errors/ErrorObservable.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.errors; 2 | 3 | import de.jlab.cardroid.devices.ObservableFeature; 4 | 5 | public interface ErrorObservable extends ObservableFeature { 6 | 7 | interface ErrorListener extends ObservableFeature.Listener { 8 | void onError(int errorNumber); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_overlay_close.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pref_rules.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dashboard_stats_vars.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/car/CanInteractable.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.car; 2 | 3 | import de.jlab.cardroid.devices.Feature; 4 | 5 | public interface CanInteractable extends Feature { 6 | void registerCanId(CanPacketDescriptor descriptor); 7 | void unregisterCanId(CanPacketDescriptor descriptor); 8 | void sendPacket(int canId, byte[] data); 9 | 10 | void startSniffer(); 11 | void stopSniffer(); 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dashboard_stats_feature.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tab_gps_raw.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/menu/action_detail_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_action_device_reset.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/menu/rule_detail_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/car/CanObservable.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.car; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import de.jlab.cardroid.devices.ObservableFeature; 6 | 7 | public interface CanObservable extends ObservableFeature { 8 | 9 | interface CanPacketListener extends ObservableFeature.Listener { 10 | void onReceive(@NonNull CanPacket packet); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/Trigger.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules; 2 | 3 | public final class Trigger { 4 | 5 | private Event event; 6 | 7 | public Trigger(Event event) { 8 | this.event = event; 9 | } 10 | 11 | public Event getEvent() { 12 | return this.event; 13 | } 14 | 15 | public boolean triggers(Event otherEvent) { 16 | return this.event.equals(otherEvent); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/actions/AudioAction.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.actions; 2 | 3 | import android.content.Context; 4 | import android.media.AudioManager; 5 | 6 | import de.jlab.cardroid.rules.Action; 7 | 8 | abstract class AudioAction extends Action { 9 | 10 | protected AudioManager getAudioManager(Context context) { 11 | return (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_action_device_reboot.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/storage/RuleDefinition.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.storage; 2 | 3 | import java.util.List; 4 | 5 | import androidx.room.Embedded; 6 | import androidx.room.Relation; 7 | 8 | public class RuleDefinition { 9 | 10 | @Embedded 11 | public EventEntity event; 12 | 13 | @Relation(parentColumn = "uid", entityColumn = "event_uid", entity = ActionEntity.class) 14 | public List actions; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/res/menu/dashboard_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pref_compatibility.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pref_overlay.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/properties/Property.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.properties; 2 | 3 | public class Property { 4 | private T value; 5 | private String key; 6 | 7 | public Property(String key, T value) { 8 | this.key = key; 9 | this.value = value; 10 | } 11 | 12 | public T getValue() { 13 | return this.value; 14 | } 15 | 16 | public String getKey() { 17 | return this.key; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_fan.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_device_feature_location.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_off.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_device_feature_errors.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_can_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/de/jlab/cardroid/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/template_flow_master_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pref_gps.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/ObservableFeature.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.annotation.Nullable; 5 | 6 | public interface ObservableFeature extends Feature { 7 | 8 | void addListener(@NonNull LT listener); 9 | void removeListener(@NonNull LT listener); 10 | 11 | void setDevice(@NonNull Device device); 12 | @Nullable 13 | Device getDevice(); 14 | 15 | interface Listener {} 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_recirculation.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/serial/carduino/EventObservable.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.serial.carduino; 2 | 3 | import androidx.annotation.NonNull; 4 | import de.jlab.cardroid.devices.ObservableFeature; 5 | import de.jlab.cardroid.devices.identification.DeviceUid; 6 | 7 | public interface EventObservable extends ObservableFeature { 8 | 9 | interface EventListener extends ObservableFeature.Listener { 10 | void onEvent(int eventNum, @NonNull DeviceUid deviceUid); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_status_off.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_status_on.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/seekarc_thumb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 11 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 115200 5 | 4800 6 | 9600 7 | 8 | 9 | 10 | 4 11 | 5 12 | 6 13 | 7 14 | 8 15 | 9 16 | 10 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pref_devices.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_action_device_delete.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/gps/GpsObservable.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.gps; 2 | 3 | import de.jlab.cardroid.devices.ObservableFeature; 4 | import de.jlab.cardroid.devices.serial.gps.GpsPosition; 5 | 6 | public interface GpsObservable extends ObservableFeature { 7 | 8 | interface PositionListener extends ObservableFeature.Listener { 9 | // TODO: Remove sentence from callback. That is serial shit that has to go somewhere else later 10 | void onUpdate(GpsPosition position, String sentence); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_ac.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dashboard_stats_devices.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/KnownEvents.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import de.jlab.cardroid.rules.storage.EventEntity; 7 | 8 | public final class KnownEvents { 9 | 10 | private Map eventMap = new HashMap<>(); 11 | 12 | public void addEvent(Event event) { 13 | this.eventMap.put(event.getDescriptor(), event); 14 | } 15 | 16 | public Event getEvent(EventEntity descriptor) { 17 | return this.eventMap.get(descriptor); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_gps_sentences.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_banner_permissions.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_device_type_unknown.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_device_feature_unknown.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_device_type_gps.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_device_list.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/usb/UsbDevice.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.usb; 2 | 3 | import android.app.Application; 4 | 5 | import androidx.annotation.NonNull; 6 | import de.jlab.cardroid.devices.Device; 7 | import de.jlab.cardroid.devices.identification.DeviceConnectionId; 8 | 9 | public abstract class UsbDevice extends Device { 10 | 11 | private android.hardware.usb.UsbDevice device; 12 | 13 | public UsbDevice(@NonNull android.hardware.usb.UsbDevice device, @NonNull Application app) { 14 | super(app); 15 | this.device = device; 16 | this.setConnectionId(DeviceConnectionId.fromUsbDevice(device)); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tab_usb.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pref_usb.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tab_gps_status.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/menu/bottom_navigation_carduino_monitor.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/menu/bottom_navigation_gps_monitor.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | 16 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/storage/EventViewListModel.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.storage; 2 | 3 | import android.app.Application; 4 | 5 | import java.util.List; 6 | 7 | import androidx.lifecycle.AndroidViewModel; 8 | import androidx.lifecycle.LiveData; 9 | 10 | public class EventViewListModel extends AndroidViewModel { 11 | 12 | private LiveData> allEvents; 13 | 14 | public EventViewListModel(Application application) { 15 | super(application); 16 | EventRepository repository = new EventRepository(application); 17 | this.allEvents = repository.getAll(); 18 | } 19 | 20 | public LiveData> getAll() { return this.allEvents; } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pref_car.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tab_car.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/FragmentActionListener.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules; 2 | 3 | import de.jlab.cardroid.rules.storage.ActionEntity; 4 | import de.jlab.cardroid.rules.storage.EventEntity; 5 | import de.jlab.cardroid.rules.storage.RuleDefinition; 6 | 7 | public interface FragmentActionListener { 8 | 9 | int COMMAND_ADD = 0; 10 | int COMMAND_EDIT = 1; 11 | int COMMAND_SAVE = 2; 12 | int COMMAND_CANCEL = 3; 13 | int COMMAND_DELETE = 4; 14 | int COMMAND_UPDATED = 5; 15 | 16 | void onEventChange(int command, EventEntity eventEntity); 17 | 18 | void onActionChange(int command, ActionEntity actionEntity); 19 | 20 | void onRuleChange(int command, RuleDefinition ruleDefinition); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/storage/EventViewDetailModel.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.storage; 2 | 3 | import android.app.Application; 4 | 5 | import androidx.lifecycle.AndroidViewModel; 6 | import androidx.lifecycle.LiveData; 7 | 8 | public class EventViewDetailModel extends AndroidViewModel { 9 | 10 | private EventRepository repository; 11 | 12 | public EventViewDetailModel(Application application) { 13 | super(application); 14 | repository = new EventRepository(application); 15 | } 16 | 17 | public LiveData getAsRule(int eventUid) { return repository.getAsRule(eventUid); } 18 | 19 | public void updateEvent(EventEntity eventEntity) { this.repository.update(eventEntity); } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_device_feature_can.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_device_type_carduino.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/storage/ActionDao.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.storage; 2 | 3 | import java.util.List; 4 | 5 | import androidx.lifecycle.LiveData; 6 | import androidx.room.Dao; 7 | import androidx.room.Delete; 8 | import androidx.room.Insert; 9 | import androidx.room.Query; 10 | import androidx.room.Update; 11 | 12 | @Dao 13 | public interface ActionDao { 14 | 15 | @Query("SELECT * FROM actions") 16 | List getAll(); 17 | 18 | @Query("SELECT * FROM actions WHERE uid =:uid") 19 | LiveData get(int uid); 20 | 21 | @Insert 22 | void insert(ActionEntity... actionEntities); 23 | 24 | @Update 25 | void update(ActionEntity... actionEntities); 26 | 27 | @Delete() 28 | void delete(ActionEntity... actionEntities); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/serial/carduino/CarduinoEventInteractable.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.serial.carduino; 2 | 3 | import de.jlab.cardroid.devices.Device; 4 | import de.jlab.cardroid.devices.usb.serial.carduino.CarduinoUsbDevice; 5 | 6 | public final class CarduinoEventInteractable implements EventInteractable { 7 | 8 | private CarduinoUsbDevice device; 9 | 10 | @Override 11 | public void sendEvent(byte eventId, byte[] payload) { 12 | this.device.send(CarduinoPacketType.createPacket(CarduinoPacketType.EVENT, eventId, payload)); 13 | } 14 | 15 | @Override 16 | public void setDevice(Device device) { 17 | this.device = (CarduinoUsbDevice)device; 18 | } 19 | 20 | @Override 21 | public Device getDevice() { 22 | return this.device; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/serial/carduino/CarduinoPacketParser.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.serial.carduino; 2 | 3 | import androidx.annotation.NonNull; 4 | import de.jlab.cardroid.devices.serial.SerialReader; 5 | 6 | public abstract class CarduinoPacketParser implements SerialReader.SerialPacketListener { 7 | 8 | @Override 9 | public final void onReceivePackets(@NonNull CarduinoSerialPacket[] packets) { 10 | for (CarduinoSerialPacket packet : packets) { 11 | if (this.shouldHandlePacket(packet)) { 12 | this.handlePacket(packet); 13 | } 14 | } 15 | } 16 | 17 | protected abstract boolean shouldHandlePacket(@NonNull CarduinoSerialPacket packet); 18 | protected abstract void handlePacket(@NonNull CarduinoSerialPacket packet); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/ui/DeviceListViewModel.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.ui; 2 | 3 | import android.app.Application; 4 | 5 | import java.util.List; 6 | 7 | import androidx.lifecycle.AndroidViewModel; 8 | import androidx.lifecycle.LiveData; 9 | import de.jlab.cardroid.devices.storage.DeviceEntity; 10 | import de.jlab.cardroid.devices.storage.DeviceRepository; 11 | 12 | public final class DeviceListViewModel extends AndroidViewModel { 13 | 14 | private LiveData> devices; 15 | 16 | public DeviceListViewModel(Application application) { 17 | super(application); 18 | DeviceRepository repository = new DeviceRepository(application); 19 | this.devices = repository.getAll(); 20 | } 21 | 22 | public LiveData> getAll() { return this.devices; } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/res/xml/pref_compatibility.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 6 | 7 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | android.useAndroidX=true 14 | android.enableJetifier=true 15 | 16 | # When configured, Gradle will run in incubating parallel mode. 17 | # This option should only be used with decoupled projects. More details, visit 18 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 19 | # org.gradle.parallel=true 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_mode_bg.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/storage/ActionViewDetailModel.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.storage; 2 | 3 | import android.app.Application; 4 | 5 | import androidx.lifecycle.AndroidViewModel; 6 | import androidx.lifecycle.LiveData; 7 | 8 | public class ActionViewDetailModel extends AndroidViewModel { 9 | 10 | private ActionRepository repository; 11 | 12 | public ActionViewDetailModel(Application application) { 13 | super(application); 14 | repository = new ActionRepository(application); 15 | } 16 | 17 | public LiveData get(int uid) { return repository.get(uid); } 18 | 19 | public void insert(ActionEntity actionEntity) { 20 | this.repository.insert(actionEntity); 21 | } 22 | 23 | public void update(ActionEntity actionEntity) { 24 | this.repository.update(actionEntity); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cc_auto.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/actions/VoiceAction.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.actions; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.speech.RecognizerIntent; 6 | 7 | import java.util.HashMap; 8 | 9 | import de.jlab.cardroid.rules.Action; 10 | import de.jlab.cardroid.rules.properties.ActionPropertyEditor; 11 | 12 | public final class VoiceAction extends Action { 13 | 14 | @Override 15 | public void execute(Context context) { 16 | Intent voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE); 17 | voiceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 18 | context.startActivity(voiceIntent); 19 | } 20 | 21 | @Override 22 | protected void setKnownProperties(HashMap knownProperties) { 23 | // Intentionally left blank 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/de/jlab/cardroid/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid; 2 | 3 | import android.content.Context; 4 | 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | 8 | import androidx.test.InstrumentationRegistry; 9 | import androidx.test.runner.AndroidJUnit4; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumentation test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() throws Exception { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getTargetContext(); 24 | 25 | assertEquals("de.jlab.cardroid", appContext.getPackageName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/Rule.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules; 2 | 3 | import android.content.Context; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | 8 | import androidx.annotation.NonNull; 9 | 10 | public final class Rule { 11 | 12 | private Trigger trigger; 13 | private ArrayList actions = new ArrayList<>(); 14 | 15 | public Rule(Trigger trigger, Action... actions) { 16 | this.trigger = trigger; 17 | Collections.addAll(this.actions, actions); 18 | } 19 | 20 | public Trigger getTrigger() { 21 | return this.trigger; 22 | } 23 | 24 | public void trigger(@NonNull Event event, @NonNull Context context) { 25 | if (this.trigger.triggers(event)) { 26 | for (Action action : this.actions) { 27 | action.execute(context); 28 | } 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/utils/StopWatch.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.utils; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | public final class StopWatch { 6 | 7 | private static final long NANOS_TO_MILLIS = 1000000; 8 | 9 | public enum Unit { 10 | NANOS(1), 11 | MILLIS(NANOS_TO_MILLIS), 12 | SECONDS(NANOS_TO_MILLIS * 1000); 13 | 14 | private long conversion; 15 | 16 | Unit(long conversion) { 17 | this.conversion = conversion; 18 | } 19 | 20 | public long convert(long nanos) { 21 | return nanos / this.conversion; 22 | } 23 | } 24 | 25 | private long start = 0; 26 | 27 | public void start() { 28 | this.start = System.nanoTime(); 29 | } 30 | 31 | public long take(@NonNull Unit unit) { 32 | return unit.convert(System.nanoTime() - this.start); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/errors/Error.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.errors; 2 | 3 | public final class Error { 4 | private int errorNumber; 5 | private long lastOccurence; 6 | private int count; 7 | 8 | public Error(int errorNumber) { 9 | this.errorNumber = errorNumber; 10 | } 11 | 12 | public void count(int errorNumber) { 13 | if (this.errorNumber == errorNumber) { 14 | this.lastOccurence = System.currentTimeMillis(); 15 | this.count++; 16 | } 17 | } 18 | 19 | public long getLastOccurence() { 20 | return lastOccurence; 21 | } 22 | 23 | public int getCount() { 24 | return this.count; 25 | } 26 | 27 | public int getErrorNumber() { 28 | return this.errorNumber; 29 | } 30 | 31 | public String getErrorCode() { 32 | return String.format("%02X", this.errorNumber); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/rule_list.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dashboard_settings.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/ui/DeviceDetailViewModel.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.ui; 2 | 3 | import android.app.Application; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.lifecycle.AndroidViewModel; 7 | import androidx.lifecycle.LiveData; 8 | import de.jlab.cardroid.devices.storage.DeviceEntity; 9 | import de.jlab.cardroid.devices.storage.DeviceRepository; 10 | 11 | public final class DeviceDetailViewModel extends AndroidViewModel { 12 | 13 | private DeviceRepository repository; 14 | 15 | public DeviceDetailViewModel(@NonNull Application application) { 16 | super(application); 17 | this.repository = new DeviceRepository(application); 18 | 19 | } 20 | 21 | public LiveData getDeviceEntity(int entityId) { 22 | return this.repository.get(entityId); 23 | } 24 | 25 | public void update(DeviceEntity entity) { 26 | this.repository.update(entity); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/properties/ActionPropertyEditor.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.properties; 2 | 3 | import android.content.Context; 4 | 5 | public interface ActionPropertyEditor { 6 | 7 | void show(Property currentValue, Context context, PropertyListener listener); 8 | PropertyValue getDefaultValue(); 9 | 10 | String getPropertyLabel(Property property, Context context); 11 | 12 | /* 13 | public Class getType() { 14 | ParameterizedType parameterizedType = (ParameterizedType)getClass().getGenericSuperclass(); 15 | Objects.requireNonNull(parameterizedType, "ActionPropertyEditor must explicitly define its generic type"); 16 | @SuppressWarnings("unchecked") 17 | Class type = (Class) parameterizedType.getActualTypeArguments()[0]; 18 | 19 | return type; 20 | } 21 | */ 22 | 23 | interface PropertyListener { 24 | void onItemSelected(PropertyValue item); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/serial/carduino/CarduinoMetaType.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.serial.carduino; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.annotation.Nullable; 5 | 6 | public enum CarduinoMetaType { 7 | CONNECTION_REQUEST(0x00), 8 | START_SNIFFING(0x0a), 9 | STOP_SNIFFING(0x0b), 10 | SET_UID(0x49), 11 | CAR_DATA_DEFINITION(0x63), 12 | BAUD_RATE_REQUEST(0x72); 13 | 14 | private byte command; 15 | 16 | CarduinoMetaType(int command) { 17 | this.command = (byte)command; 18 | } 19 | 20 | public boolean equals(byte type) { 21 | return this.command == type; 22 | } 23 | 24 | public byte getType() { 25 | return this.command; 26 | } 27 | 28 | public static CarduinoSerialPacket createPacket(@NonNull CarduinoMetaType event, @Nullable byte[] payload) { 29 | return CarduinoPacketType.createPacket(CarduinoPacketType.META, event.command, payload); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/storage/DeviceConverters.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.storage; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | 8 | import androidx.room.TypeConverter; 9 | import de.jlab.cardroid.devices.identification.DeviceUid; 10 | 11 | public final class DeviceConverters { 12 | 13 | @TypeConverter 14 | public static ArrayList readFeatures(String value) { 15 | return new ArrayList<>(Arrays.asList(TextUtils.split(value, ","))); 16 | } 17 | 18 | @TypeConverter 19 | public static String writeFeatures(ArrayList list) { 20 | return TextUtils.join(",", list); 21 | } 22 | 23 | @TypeConverter 24 | public static DeviceUid readDeviceUid(String value) { 25 | return new DeviceUid(value); 26 | } 27 | 28 | @TypeConverter 29 | public static String writeDeviceUid(DeviceUid uid) { 30 | return uid.toString(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\tools\development\android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/utils/permissions/StandardPermission.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.utils.permissions; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.annotation.StringRes; 8 | import androidx.core.app.ActivityCompat; 9 | import androidx.core.content.PermissionChecker; 10 | 11 | public final class StandardPermission extends Permission { 12 | 13 | public StandardPermission(@NonNull String permissionKey, @NonNull Constraint constraint, @StringRes int info) { 14 | super(permissionKey, constraint, info); 15 | } 16 | 17 | @Override 18 | public boolean isGranted(@NonNull Context context) { 19 | return PermissionChecker.checkSelfPermission(context, this.getPermissionKey()) == PermissionChecker.PERMISSION_GRANTED; 20 | } 21 | 22 | @Override 23 | public void request(@NonNull Activity activity) { 24 | ActivityCompat.requestPermissions(activity, new String[] { this.getPermissionKey() }, 1337); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout-w900dp/template_flow_master_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 16 | 17 | 21 | 22 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/serial/gps/GpsSatellite.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.serial.gps; 2 | 3 | public final class GpsSatellite { 4 | 5 | private int prn = 0; 6 | private float elevation = 0; 7 | private float azimuth = 0; 8 | private int snr = 0; 9 | 10 | private long lastUpdate = 0; 11 | 12 | public GpsSatellite(int prn) { 13 | this.prn = prn; 14 | } 15 | 16 | public int getPrn() { 17 | return prn; 18 | } 19 | 20 | public float getElevation() { 21 | return elevation; 22 | } 23 | 24 | public float getAzimuth() { 25 | return azimuth; 26 | } 27 | 28 | public int getSnr() { 29 | return snr; 30 | } 31 | 32 | public long getLastUpdate() { 33 | return this.lastUpdate; 34 | } 35 | 36 | public void update(float elevation, float azimuth, int snr) { 37 | this.elevation = elevation; 38 | this.azimuth = azimuth; 39 | this.snr = snr; 40 | this.lastUpdate = System.currentTimeMillis(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/storage/DeviceDao.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.storage; 2 | 3 | import java.util.List; 4 | 5 | import androidx.lifecycle.LiveData; 6 | import androidx.room.Dao; 7 | import androidx.room.Delete; 8 | import androidx.room.Insert; 9 | import androidx.room.Query; 10 | import androidx.room.Update; 11 | 12 | @Dao 13 | public interface DeviceDao { 14 | 15 | @Query("SELECT * FROM devices ORDER BY display_name ASC") 16 | List getAllSynchronous(); 17 | 18 | @Query("SELECT * FROM devices ORDER BY display_name ASC") 19 | LiveData> getAll(); 20 | 21 | @Query("SELECT * FROM devices WHERE uid = :uid") 22 | LiveData get(int uid); 23 | 24 | @Query("SELECT * FROM devices WHERE device_uid = :deviceUid") 25 | List getSynchronous(String deviceUid); 26 | 27 | @Insert 28 | void insert(DeviceEntity... deviceEntities); 29 | 30 | @Update 31 | void update(DeviceEntity... deviceEntities); 32 | 33 | @Delete() 34 | void delete(DeviceEntity... deviceEntities); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/storage/EventDao.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.storage; 2 | 3 | import java.util.List; 4 | 5 | import androidx.lifecycle.LiveData; 6 | import androidx.room.Dao; 7 | import androidx.room.Insert; 8 | import androidx.room.OnConflictStrategy; 9 | import androidx.room.Query; 10 | import androidx.room.Transaction; 11 | import androidx.room.Update; 12 | 13 | @Dao 14 | public interface EventDao { 15 | 16 | @Query("SELECT * FROM events") 17 | LiveData> getAll(); 18 | 19 | @Query("SELECT * FROM events WHERE identifier =:identifier") 20 | LiveData get(int identifier); 21 | 22 | @Transaction 23 | @Query("SELECT * FROM events") 24 | LiveData> getAllRules(); 25 | 26 | @Transaction 27 | @Query("SELECT * FROM events WHERE uid =:eventUid") 28 | LiveData getAsRule(int eventUid); 29 | 30 | @Insert(onConflict = OnConflictStrategy.IGNORE) 31 | void insert(EventEntity... eventEntities); 32 | 33 | @Update 34 | void update(EventEntity... eventEntities); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_dashboard_toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 16 | 18 | 22 | 23 | 24 | 30 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/actions/KillAppAction.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.actions; 2 | 3 | import android.app.ActivityManager; 4 | import android.content.Context; 5 | 6 | import java.util.HashMap; 7 | 8 | import de.jlab.cardroid.rules.Action; 9 | import de.jlab.cardroid.rules.properties.ActionPropertyEditor; 10 | import de.jlab.cardroid.rules.properties.AppSelectionPropertyEditor; 11 | 12 | public final class KillAppAction extends Action { 13 | 14 | private static final String PREFIX = "action_killapp"; 15 | 16 | private static final String PROPERTY_PACKAGE = PREFIX + "_package"; 17 | 18 | @Override 19 | public void execute(Context context) { 20 | ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 21 | am.restartPackage(PROPERTY_PACKAGE); 22 | am.killBackgroundProcesses((String)getPropertyValue(PROPERTY_PACKAGE)); 23 | } 24 | 25 | @Override 26 | protected void setKnownProperties(HashMap knownProperties) { 27 | knownProperties.put(PROPERTY_PACKAGE, new AppSelectionPropertyEditor()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/serial/gps/GpsSerialReader.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.serial.gps; 2 | 3 | import java.util.ArrayList; 4 | 5 | import androidx.annotation.NonNull; 6 | import de.jlab.cardroid.devices.serial.SerialReader; 7 | 8 | public final class GpsSerialReader extends SerialReader { 9 | 10 | private StringBuilder dataLine = new StringBuilder(); 11 | 12 | @Override 13 | protected GpsSerialPacket[] createPackets(@NonNull byte[] data) { 14 | ArrayList packets = new ArrayList<>(); 15 | for (byte dataByte : data) { 16 | if (dataByte == 0x0D || dataByte == 0x0A) { 17 | continue; 18 | } else if (dataByte == 0x24) { 19 | String rawData = this.dataLine.toString(); 20 | if (rawData.startsWith("$")) { 21 | packets.add(new GpsSerialPacket(this.dataLine.toString())); 22 | } 23 | this.dataLine.setLength(0); 24 | } 25 | this.dataLine.append((char) dataByte); 26 | } 27 | return packets.toArray(new GpsSerialPacket[0]); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/overlay/SeekArcEvent.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.overlay; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | public final class SeekArcEvent { 6 | 7 | public enum Type { 8 | TRACKING_STARTED, 9 | TRACKING_STOPPED, 10 | PROGRESS_CHANGED 11 | } 12 | 13 | private SeekArc seekArc; 14 | private Type type = Type.TRACKING_STARTED; 15 | private int progress = 0; 16 | private boolean isUserEvent = false; 17 | 18 | public SeekArcEvent(@NonNull SeekArc seekArc) { 19 | this.seekArc = seekArc; 20 | } 21 | 22 | public void update(int progress, boolean isUserEvent, @NonNull Type type) { 23 | this.progress = progress; 24 | this.isUserEvent = isUserEvent; 25 | this.type = type; 26 | } 27 | 28 | public int getProgress() { 29 | return this.progress; 30 | } 31 | 32 | @NonNull 33 | public SeekArc getSeekArc() { 34 | return this.seekArc; 35 | } 36 | 37 | public boolean isUserEvent() { 38 | return this.isUserEvent; 39 | } 40 | 41 | @NonNull 42 | public Type getType() { 43 | return this.type; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/Event.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules; 2 | 3 | import android.content.Context; 4 | 5 | import java.util.Objects; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.annotation.Nullable; 9 | import de.jlab.cardroid.R; 10 | import de.jlab.cardroid.rules.storage.EventEntity; 11 | 12 | public final class Event { 13 | 14 | private EventEntity descriptor; 15 | 16 | public Event(EventEntity descriptor) { 17 | this.descriptor = descriptor; 18 | } 19 | 20 | public EventEntity getDescriptor() { 21 | return this.descriptor; 22 | } 23 | 24 | public static String getLocalizedNameFromIdentifier(int identifier, @NonNull Context context) { 25 | int resId = context.getResources().getIdentifier("event_" + identifier, "string", context.getPackageName()); 26 | if (resId > 0) { 27 | return context.getResources().getString(resId); 28 | } 29 | return context.getResources().getString(R.string.event_unknown, identifier); 30 | } 31 | 32 | public boolean equals(@Nullable Event other) { 33 | return other != null && Objects.equals(this.descriptor, other.descriptor); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_dashboard_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 16 | 18 | 24 | 25 | 26 | 32 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/actions/StartAppAction.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.actions; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import java.util.HashMap; 7 | 8 | import de.jlab.cardroid.rules.Action; 9 | import de.jlab.cardroid.rules.properties.ActionPropertyEditor; 10 | import de.jlab.cardroid.rules.properties.AppSelectionPropertyEditor; 11 | 12 | public final class StartAppAction extends Action { 13 | 14 | private static final String PREFIX = "action_startapp"; 15 | 16 | private static final String PROPERTY_PACKAGE = PREFIX + "_package"; 17 | 18 | @Override 19 | public void execute(Context context) { 20 | Intent intent = context.getPackageManager().getLaunchIntentForPackage((String)getPropertyValue(PROPERTY_PACKAGE)); 21 | if (intent != null) { 22 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 23 | context.startActivity(intent); 24 | } 25 | // TODO handle case of uninstalled app 26 | } 27 | 28 | @Override 29 | protected void setKnownProperties(HashMap knownProperties) { 30 | knownProperties.put(PROPERTY_PACKAGE, new AppSelectionPropertyEditor()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/serial/carduino/CarduinoEventType.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.serial.carduino; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.annotation.Nullable; 5 | 6 | /** 7 | * @Deprecated Hardcoded event types are part of the LegacyDevice. The possible events should 8 | * be broadcasted by the device on handshake and then made available as an option in the user 9 | * interface when designing custom screens. 10 | */ 11 | @Deprecated 12 | public enum CarduinoEventType { 13 | CC_OFF_BUTTON(0x01), 14 | CC_AC_BUTTON(0x02), 15 | CC_AUTO_BUTTON(0x03), 16 | CC_RECIRCULATION_BUTTON(0x04), 17 | CC_WSH_BUTTON(0x05), 18 | CC_RWH_BUTTON(0x06), 19 | CC_MODE_BUTTON(0x07), 20 | CC_TEMPERATURE(0x08), 21 | CC_FAN_LEVEL(0x09); 22 | 23 | private byte command; 24 | 25 | CarduinoEventType(int command) { 26 | this.command = (byte)command; 27 | } 28 | 29 | public byte getCommand() { 30 | return this.command; 31 | } 32 | 33 | public static CarduinoSerialPacket createPacket(@NonNull CarduinoEventType event, @Nullable byte[] payload) { 34 | return CarduinoPacketType.createPacket(CarduinoPacketType.EVENT, event.command, payload); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/devices/identification/DeviceConnectionId.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.devices.identification; 2 | 3 | import android.bluetooth.BluetoothDevice; 4 | import android.hardware.usb.UsbDevice; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.annotation.Nullable; 8 | 9 | public final class DeviceConnectionId { 10 | 11 | private String connectionId; 12 | 13 | private DeviceConnectionId(String connectionId) { 14 | this.connectionId = connectionId; 15 | } 16 | 17 | public static DeviceConnectionId fromUsbDevice(@NonNull UsbDevice device) { 18 | return new DeviceConnectionId(device.getDeviceName()); 19 | } 20 | 21 | public static DeviceConnectionId fromBluetoothDevice(@NonNull BluetoothDevice device) { 22 | return new DeviceConnectionId(device.getAddress()); 23 | } 24 | 25 | public boolean equals(@Nullable DeviceConnectionId other) { 26 | return other != null && this.connectionId.equals(other.connectionId); 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return this.connectionId.hashCode(); 32 | } 33 | 34 | @NonNull 35 | @Override 36 | public String toString() { 37 | return this.connectionId; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/ActionDefinition.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | public class ActionDefinition { 8 | private Class actionType = null; 9 | private String label = null; 10 | 11 | public ActionDefinition(@NonNull Class actionType, Context context) { 12 | this.actionType = actionType; 13 | this.label = getLocalizedNameFromClassName(actionType.getSimpleName(), context); 14 | } 15 | 16 | public Class getActionType() { 17 | return this.actionType; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return this.label; 23 | } 24 | 25 | public static String getLocalizedNameFromClassName(@NonNull String className, Context context) { 26 | String identifier = className.substring(className.lastIndexOf('.') + 1).replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase(); 27 | int resId = context.getResources().getIdentifier(identifier, "string", context.getPackageName()); 28 | if (resId > 0) { 29 | return context.getResources().getString(resId); 30 | } 31 | return identifier; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/utils/ui/UnitValues.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.utils.ui; 2 | 3 | import android.content.Context; 4 | import android.text.Html; 5 | import android.text.Spanned; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.annotation.StringRes; 9 | import de.jlab.cardroid.R; 10 | 11 | public final class UnitValues { 12 | 13 | public static Spanned getFancyDecimalValue(float value) { 14 | String[] parts = Float.toString(value).split("\\."); 15 | String decimals = parts.length > 1 ? "." + parts[1] + "" : ""; 16 | return Html.fromHtml(parts[0] + decimals); 17 | } 18 | 19 | public static int constrainToRange(int value, int min, int max) { 20 | return Math.max(min, Math.min(value, max)); 21 | } 22 | 23 | public static float constrainToRange(float value, float min, float max) { 24 | return Math.max(min, Math.min(value, max)); 25 | } 26 | 27 | public static String getStatisticString(int count, int average, @StringRes int unit, @NonNull Context context) { 28 | return context.getString( 29 | R.string.status_statistics_value, 30 | count, 31 | context.getString(unit), 32 | average 33 | ); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/de/jlab/cardroid/rules/properties/PropertyValue.java: -------------------------------------------------------------------------------- 1 | package de.jlab.cardroid.rules.properties; 2 | 3 | import android.content.Context; 4 | 5 | import java.util.Objects; 6 | 7 | import androidx.annotation.NonNull; 8 | 9 | public class PropertyValue { 10 | private T value; 11 | private String name; 12 | 13 | public PropertyValue(T value, String name) { 14 | this.value = value; 15 | this.name = name; 16 | } 17 | 18 | public T getValue() { 19 | return this.value; 20 | } 21 | 22 | public String getName() { 23 | return this.name; 24 | } 25 | 26 | public String getLabel(Context context) { 27 | String key = this.name.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase(); 28 | int resId = context.getResources().getIdentifier(key, "string", context.getPackageName()); 29 | if (resId > 0) { 30 | return context.getResources().getString(resId); 31 | } 32 | return key; 33 | } 34 | 35 | @NonNull 36 | @Override 37 | public String toString() { 38 | return this.value.toString(); 39 | } 40 | 41 | public boolean equals(@NonNull PropertyValue otherValue) { 42 | return Objects.equals(otherValue.value, this.value); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 15 | 16 | 19 | 20 | 23 | 24 | 28 | 29 |