├── docs
├── banner.png
├── lokalise.png
└── webhook_settings_1.png
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── automotive
└── src
│ ├── main
│ ├── ic_launcher-playstore.png
│ ├── ic_launcher_alt-playstore.png
│ ├── ic_launcher_alt2-playstore.png
│ ├── ic_launcher_club-playstore.png
│ ├── res
│ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_abrp.png
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ ├── ic_launcher_notification.png
│ │ │ └── ic_launcher_foreground_dev.webp
│ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_foreground_dev.webp
│ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_foreground_dev.webp
│ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_foreground_dev.webp
│ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_foreground_dev.webp
│ │ ├── drawable
│ │ │ ├── pressed_foreground.xml
│ │ │ ├── bg_multibutton.xml
│ │ │ ├── bg_club.xml
│ │ │ ├── ic_launcher_background.xml
│ │ │ ├── bg_main_tile.xml
│ │ │ ├── bg_action_bar.xml
│ │ │ ├── bg_content.xml
│ │ │ ├── club_thumb.xml
│ │ │ ├── club_button.xml
│ │ │ ├── ic_chevron_back.xml
│ │ │ ├── ic_chevron_up.xml
│ │ │ ├── ic_chevron_left.xml
│ │ │ ├── ic_chevron_right.xml
│ │ │ ├── ic_filter_active.xml
│ │ │ ├── ic_arrow_diagonal.xml
│ │ │ ├── ic_arrow_back.xml
│ │ │ ├── ic_filter.xml
│ │ │ ├── ic_battery.xml
│ │ │ ├── ic_avg_consumption.xml
│ │ │ ├── ic_close.xml
│ │ │ ├── ic_kill.xml
│ │ │ ├── ic_notification_phone.xml
│ │ │ ├── ic_upload.xml
│ │ │ ├── ic_marker_charge.xml
│ │ │ ├── ic_send.xml
│ │ │ ├── ic_marker_park.xml
│ │ │ ├── ic_power.xml
│ │ │ ├── ic_altitude.xml
│ │ │ ├── ic_energy_large.xml
│ │ │ ├── ic_login.xml
│ │ │ ├── ic_copy.xml
│ │ │ ├── ic_mail.xml
│ │ │ ├── ic_checked_checkbox.xml
│ │ │ ├── ic_notification_diagram.xml
│ │ │ ├── ic_temperature.xml
│ │ │ ├── ic_api.xml
│ │ │ ├── ic_phone.xml
│ │ │ ├── club_button_off.xml
│ │ │ ├── ic_diagram.xml
│ │ │ ├── ic_time.xml
│ │ │ ├── ic_error.xml
│ │ │ ├── ic_delete.xml
│ │ │ ├── club_gradient_radial.xml
│ │ │ ├── club_button_on.xml
│ │ │ ├── ic_save.xml
│ │ │ ├── ic_day.xml
│ │ │ ├── ic_car_app_feedback.xml
│ │ │ ├── ic_location_on.xml
│ │ │ ├── ic_charger.xml
│ │ │ ├── ic_reset.xml
│ │ │ ├── ic_connected.xml
│ │ │ ├── ic_link.xml
│ │ │ ├── ic_history.xml
│ │ │ ├── ic_distance.xml
│ │ │ ├── ic_car.xml
│ │ │ ├── ic_month.xml
│ │ │ ├── ic_camera.xml
│ │ │ ├── ic_construction.xml
│ │ │ ├── ic_temperature_large.xml
│ │ │ ├── ic_hand.xml
│ │ │ ├── ic_checkmark.xml
│ │ │ ├── ic_remaining_range.xml
│ │ │ ├── ic_coffee.xml
│ │ │ ├── ic_location_error.xml
│ │ │ ├── ic_time_large.xml
│ │ │ ├── ic_info.xml
│ │ │ ├── ic_distance_large.xml
│ │ │ ├── ic_list.xml
│ │ │ ├── ic_speed.xml
│ │ │ ├── ic_speed_large.xml
│ │ │ ├── club_gradient.xml
│ │ │ ├── ic_debug.xml
│ │ │ ├── club_thumb_off.xml
│ │ │ ├── club_thumb_on.xml
│ │ │ ├── ic_help.xml
│ │ │ ├── ic_performance.xml
│ │ │ ├── ic_webhook.xml
│ │ │ ├── ic_trip_start.xml
│ │ │ └── ic_trip_charging_location.xml
│ │ ├── anim
│ │ │ ├── slide_in_left.xml
│ │ │ ├── slide_out_left.xml
│ │ │ ├── slide_in_up.xml
│ │ │ ├── snackbar_up.xml
│ │ │ ├── stay_still.xml
│ │ │ ├── slide_in_right.xml
│ │ │ ├── slide_out_down.xml
│ │ │ ├── slide_out_right.xml
│ │ │ └── snackbar_down.xml
│ │ ├── color
│ │ │ ├── switch_tint.xml
│ │ │ ├── button_foreground.xml
│ │ │ └── button_text.xml
│ │ ├── mipmap-anydpi-v26
│ │ │ └── ic_launcher.xml
│ │ ├── values
│ │ │ ├── broadcast_actions.xml
│ │ │ ├── dimens.xml
│ │ │ └── themes.xml
│ │ ├── layout
│ │ │ ├── widget_fixed_switch.xml
│ │ │ ├── activity_permissions.xml
│ │ │ └── widget_multi_select.xml
│ │ ├── values-sw700dp-land
│ │ │ └── dimens.xml
│ │ ├── values-sw1000dp
│ │ │ └── dimens.xml
│ │ └── values-w877dp
│ │ │ └── styles.xml
│ ├── ic_launcher_alt_dev-playstore.png
│ ├── ic_launcher_alt2_dev-playstore.png
│ ├── ic_launcher_club_dev-playstore.png
│ ├── java
│ │ └── com
│ │ │ └── ixam97
│ │ │ └── carStatsViewer
│ │ │ ├── database
│ │ │ ├── tripData
│ │ │ │ ├── PointMarkerType.kt
│ │ │ │ ├── SessionMarkerType.kt
│ │ │ │ ├── TripType.kt
│ │ │ │ └── TripDataDatabase.kt
│ │ │ └── log
│ │ │ │ ├── LogDatabase.kt
│ │ │ │ ├── LogEntry.kt
│ │ │ │ └── LogDao.kt
│ │ │ ├── ui
│ │ │ ├── plot
│ │ │ │ ├── enums
│ │ │ │ │ ├── PlotDirection.kt
│ │ │ │ │ ├── PlotLabelPosition.kt
│ │ │ │ │ ├── PlotSessionGapRendering.kt
│ │ │ │ │ ├── PlotDimensionSmoothingType.kt
│ │ │ │ │ ├── PlotLineLabelFormat.kt
│ │ │ │ │ ├── PlotHighlightMethod.kt
│ │ │ │ │ ├── PlotDimensionY.kt
│ │ │ │ │ ├── PlotDimensionX.kt
│ │ │ │ │ ├── PlotMarkerType.kt
│ │ │ │ │ └── PlotLineMarkerType.kt
│ │ │ │ ├── objects
│ │ │ │ │ ├── PlotPoint.kt
│ │ │ │ │ ├── PlotRange.kt
│ │ │ │ │ └── PlotLineConfiguration.kt
│ │ │ │ └── graphics
│ │ │ │ │ ├── PlotLinePaint.kt
│ │ │ │ │ └── PlotMarkerPaint.kt
│ │ │ └── views
│ │ │ │ ├── MultiLineRowButtonWidget.kt
│ │ │ │ └── FixedSwitchWidget.kt
│ │ │ ├── utils
│ │ │ ├── Exclude.kt
│ │ │ ├── GetColorFromAttribute.kt
│ │ │ ├── SetContentViewAndTheme.kt
│ │ │ ├── FlowThrottle.kt
│ │ │ ├── WatchdogState.kt
│ │ │ ├── Ticker.kt
│ │ │ ├── TimestampSynchronizer.kt
│ │ │ ├── GetBitmapFromVectorDrawable.kt
│ │ │ ├── Watchdog.kt
│ │ │ ├── TimeTracker.kt
│ │ │ └── ChangeLogCreator.kt
│ │ │ ├── repository
│ │ │ └── logSubmit
│ │ │ │ ├── LogSubmitService.kt
│ │ │ │ ├── LogSubmitApi.kt
│ │ │ │ └── LogSubmit.kt
│ │ │ ├── compose
│ │ │ ├── theme
│ │ │ │ ├── Shape.kt
│ │ │ │ └── Color.kt
│ │ │ ├── Event.kt
│ │ │ ├── screens
│ │ │ │ ├── settings
│ │ │ │ │ ├── Changelog.kt
│ │ │ │ │ ├── GeneralSettings.kt
│ │ │ │ │ └── PrivacySettings.kt
│ │ │ │ └── MapboxScreen.kt
│ │ │ ├── components
│ │ │ │ ├── CarIconButton.kt
│ │ │ │ └── CarSwitchRow.kt
│ │ │ ├── ComposeSettingsActivity.kt
│ │ │ └── ComposeTripDetailsActivity.kt
│ │ │ ├── liveDataApi
│ │ │ ├── abrpLiveData
│ │ │ │ ├── AbrpDataSet.kt
│ │ │ │ └── AppPreferencesExt.kt
│ │ │ └── http
│ │ │ │ ├── HttpDataSet.kt
│ │ │ │ ├── TextValidator.kt
│ │ │ │ └── AppPreferencesExt.kt
│ │ │ ├── dataProcessor
│ │ │ ├── DrivingState.kt
│ │ │ ├── IgnitionState.kt
│ │ │ ├── StaticVehicleData.kt
│ │ │ └── RealTimeData.kt
│ │ │ ├── locationClient
│ │ │ ├── LocationClient.kt
│ │ │ └── ContextHasLocationPermission.kt
│ │ │ ├── carPropertiesClient
│ │ │ └── CarProperty.kt
│ │ │ ├── appPreferences
│ │ │ └── AppPreference.kt
│ │ │ └── map
│ │ │ └── MapboxInterface.kt
│ └── AndroidManifest.xml
│ ├── carapp
│ ├── res
│ │ ├── xml
│ │ │ └── automotive_app_desc.xml
│ │ ├── values
│ │ │ └── strings.xml
│ │ └── drawable
│ │ │ ├── ic_car_app_minus.xml
│ │ │ ├── ic_car_app_plus.xml
│ │ │ ├── ic_car_app_menu.xml
│ │ │ ├── ic_car_app_upgrade.xml
│ │ │ ├── ic_car_app_altitude.xml
│ │ │ ├── ic_car_app_tune.xml
│ │ │ ├── ic_car_app_battery.xml
│ │ │ ├── ic_car_app_check.xml
│ │ │ ├── ic_car_app_reset.xml
│ │ │ ├── ic_car_app_dashboard.xml
│ │ │ ├── ic_car_app_history.xml
│ │ │ ├── ic_car_app_canvas.xml
│ │ │ ├── ic_car_app_status.xml
│ │ │ ├── ic_car_app_debug.xml
│ │ │ ├── ic_car_app_list.xml
│ │ │ ├── ic_car_app_speed.xml
│ │ │ └── ic_car_app_settings.xml
│ └── java
│ │ └── com
│ │ └── ixam97
│ │ └── carStatsViewer
│ │ └── carApp
│ │ ├── renderer
│ │ └── Renderer.kt
│ │ ├── CarStatsViewerService.kt
│ │ ├── DevNoticeScreen.kt
│ │ ├── ChargingSessionDetailsScreen.kt
│ │ ├── RealTimeDataScreen.kt
│ │ ├── ConfirmResetScreen.kt
│ │ ├── utils
│ │ └── Utils.kt
│ │ └── ConfirmDeleteTripScreen.kt
│ ├── legacy
│ └── res
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher_foreground.webp
│ │ └── ic_launcher_foreground_dev.webp
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher_foreground.webp
│ │ └── ic_launcher_foreground_dev.webp
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher_foreground.webp
│ │ └── ic_launcher_foreground_dev.webp
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher_foreground.webp
│ │ └── ic_launcher_foreground_dev.webp
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher_foreground.webp
│ │ └── ic_launcher_foreground_dev.webp
│ │ └── drawable
│ │ └── ic_launcher_background.xml
│ ├── mapboxdummy
│ └── java
│ │ └── com
│ │ └── ixam97
│ │ └── carStatsViewer
│ │ └── map
│ │ └── Mapbox.kt
│ ├── dev
│ └── res
│ │ ├── values
│ │ ├── preferences_keys.xml
│ │ └── strings.xml
│ │ └── mipmap-anydpi-v26
│ │ └── ic_launcher.xml
│ └── devCarapp
│ ├── res
│ └── values
│ │ └── strings.xml
│ └── AndroidManifest.xml
├── config
└── libraries
│ └── egm96.json
├── .github
├── workflows
│ └── build.yml
└── FUNDING.yml
├── .gitignore
├── LICENSE.md
├── settings.gradle
├── gradle.properties
└── gradlew.bat
/docs/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/docs/banner.png
--------------------------------------------------------------------------------
/docs/lokalise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/docs/lokalise.png
--------------------------------------------------------------------------------
/docs/webhook_settings_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/docs/webhook_settings_1.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/automotive/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/automotive/src/main/ic_launcher_alt-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/ic_launcher_alt-playstore.png
--------------------------------------------------------------------------------
/automotive/src/main/ic_launcher_alt2-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/ic_launcher_alt2-playstore.png
--------------------------------------------------------------------------------
/automotive/src/main/ic_launcher_club-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/ic_launcher_club-playstore.png
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-xxxhdpi/ic_abrp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-xxxhdpi/ic_abrp.png
--------------------------------------------------------------------------------
/automotive/src/main/ic_launcher_alt_dev-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/ic_launcher_alt_dev-playstore.png
--------------------------------------------------------------------------------
/automotive/src/carapp/res/xml/automotive_app_desc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/automotive/src/main/ic_launcher_alt2_dev-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/ic_launcher_alt2_dev-playstore.png
--------------------------------------------------------------------------------
/automotive/src/main/ic_launcher_club_dev-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/ic_launcher_club_dev-playstore.png
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/database/tripData/PointMarkerType.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.database.tripData
2 |
3 | object PointMarkerType {
4 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/automotive/src/legacy/res/mipmap-hdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/legacy/res/mipmap-hdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/automotive/src/legacy/res/mipmap-mdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/legacy/res/mipmap-mdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/automotive/src/legacy/res/mipmap-xhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/legacy/res/mipmap-xhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/automotive/src/legacy/res/mipmap-xxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/legacy/res/mipmap-xxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/automotive/src/legacy/res/mipmap-xxxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/legacy/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-hdpi/ic_launcher_foreground_dev.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-hdpi/ic_launcher_foreground_dev.webp
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-mdpi/ic_launcher_foreground_dev.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-mdpi/ic_launcher_foreground_dev.webp
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-xhdpi/ic_launcher_foreground_dev.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-xhdpi/ic_launcher_foreground_dev.webp
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher_notification.png
--------------------------------------------------------------------------------
/automotive/src/legacy/res/mipmap-hdpi/ic_launcher_foreground_dev.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/legacy/res/mipmap-hdpi/ic_launcher_foreground_dev.webp
--------------------------------------------------------------------------------
/automotive/src/legacy/res/mipmap-mdpi/ic_launcher_foreground_dev.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/legacy/res/mipmap-mdpi/ic_launcher_foreground_dev.webp
--------------------------------------------------------------------------------
/automotive/src/legacy/res/mipmap-xhdpi/ic_launcher_foreground_dev.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/legacy/res/mipmap-xhdpi/ic_launcher_foreground_dev.webp
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-xxhdpi/ic_launcher_foreground_dev.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-xxhdpi/ic_launcher_foreground_dev.webp
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground_dev.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground_dev.webp
--------------------------------------------------------------------------------
/automotive/src/legacy/res/mipmap-xxhdpi/ic_launcher_foreground_dev.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/legacy/res/mipmap-xxhdpi/ic_launcher_foreground_dev.webp
--------------------------------------------------------------------------------
/automotive/src/legacy/res/mipmap-xxxhdpi/ic_launcher_foreground_dev.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ixam97/CarStatsViewer/HEAD/automotive/src/legacy/res/mipmap-xxxhdpi/ic_launcher_foreground_dev.webp
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/enums/PlotDirection.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.enums
2 |
3 | enum class PlotDirection {
4 | LEFT_TO_RIGHT, RIGHT_TO_LEFT
5 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/enums/PlotLabelPosition.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.enums
2 |
3 | enum class PlotLabelPosition {
4 | LEFT, RIGHT, NONE
5 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/enums/PlotSessionGapRendering.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.enums
2 |
3 | enum class PlotSessionGapRendering {
4 | NONE, JOIN, CIRCLE, GAP
5 | }
--------------------------------------------------------------------------------
/automotive/src/mapboxdummy/java/com/ixam97/carStatsViewer/map/Mapbox.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.map
2 |
3 | // This is a dummy class
4 | object Mapbox: MapboxInterface {
5 | override fun isDummy() = true
6 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/enums/PlotDimensionSmoothingType.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.enums
2 |
3 | enum class PlotDimensionSmoothingType {
4 | VALUE, PERCENTAGE, PIXEL
5 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/objects/PlotPoint.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.objects
2 |
3 | class PlotPoint(
4 | val x: Float,
5 | val y: PlotLineItem,
6 | val group: Any)
--------------------------------------------------------------------------------
/automotive/src/dev/res/values/preferences_keys.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | com.ixam97.carStatsViewer_dev.preferences
4 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/database/tripData/SessionMarkerType.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.database.tripData
2 |
3 | object SessionMarkerType {
4 | const val PARK = 2
5 | const val CHARGE = 1
6 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/enums/PlotLineLabelFormat.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.enums
2 |
3 | enum class PlotLineLabelFormat {
4 | NUMBER, FLOAT, PERCENTAGE, TIME, DISTANCE, ALTITUDE
5 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/pressed_foreground.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/automotive/src/main/res/anim/slide_in_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
--------------------------------------------------------------------------------
/automotive/src/main/res/anim/slide_out_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/bg_multibutton.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/automotive/src/dev/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Car Stats Viewer (Dev)
4 | CSV (Dev)
5 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Car Stats Viewer (Play Edition)
4 | CSV (Play)
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Jun 25 15:11:26 PDT 2020
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-8.13-all.zip
7 |
--------------------------------------------------------------------------------
/automotive/src/devCarapp/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Car Stats Viewer (Play Edition, Dev)
4 | CSV (Play, Dev)
5 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/enums/PlotHighlightMethod.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.enums
2 |
3 | enum class PlotHighlightMethod {
4 | MIN, MAX, FIRST, LAST, AVG_BY_DIMENSION, AVG_BY_INDEX, AVG_BY_DISTANCE, AVG_BY_TIME, AVG_BY_STATE_OF_CHARGE, RAW, NONE
5 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/utils/Exclude.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.utils
2 |
3 | import java.lang.annotation.Retention
4 | import java.lang.annotation.RetentionPolicy
5 |
6 | @Retention(RetentionPolicy.RUNTIME)
7 | @Target(AnnotationTarget.FIELD)
8 | annotation class Exclude
--------------------------------------------------------------------------------
/automotive/src/main/res/color/switch_tint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/automotive/src/main/res/anim/slide_in_up.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/automotive/src/main/res/anim/snackbar_up.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/automotive/src/main/res/anim/stay_still.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/bg_club.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/automotive/src/main/res/anim/slide_in_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/automotive/src/main/res/anim/slide_out_down.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/automotive/src/main/res/anim/slide_out_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/automotive/src/main/res/anim/snackbar_down.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/automotive/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/automotive/src/dev/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/bg_main_tile.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/database/log/LogDatabase.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.database.log
2 |
3 | import androidx.room.Database
4 | import androidx.room.RoomDatabase
5 |
6 | @Database(entities = [LogEntry::class], version = 1)
7 | abstract class LogDatabase: RoomDatabase() {
8 | abstract fun logDao(): LogDao
9 | }
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/bg_action_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/bg_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/config/libraries/egm96.json:
--------------------------------------------------------------------------------
1 | {
2 | "uniqueId": "com.github.matthiaszimmermann:EGM96",
3 | "developers": [
4 | {
5 | "name" : "Matthias Zimmermann"
6 | }
7 | ],
8 | "artifactVersion": "master-SNAPSHOT",
9 | "description": "",
10 | "name": "EGM96",
11 | "licenses": [
12 | "MIT"
13 | ],
14 | "website": "https://github.com/matthiaszimmermann/EGM96"
15 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/club_thumb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/repository/logSubmit/LogSubmitService.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.repository.logSubmit
2 |
3 | import android.app.Service
4 | import android.content.Intent
5 | import android.os.IBinder
6 |
7 | class LogSubmitService: Service() {
8 |
9 | override fun onBind(p0: Intent?): IBinder? {
10 | return null
11 | }
12 |
13 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/club_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/objects/PlotRange.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.objects
2 |
3 | class PlotRange(
4 | val minNegative: Float? = null,
5 | val minPositive: Float? = null,
6 | val maxNegative: Float? = null,
7 | val maxPositive: Float? = null,
8 | val smoothAxis : Float? = null,
9 | val backgroundZero : Float? = null
10 | )
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/utils/GetColorFromAttribute.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.utils
2 |
3 | import android.content.Context
4 | import android.util.TypedValue
5 |
6 | fun getColorFromAttribute(context: Context, attrId: Int): Int {
7 | val typedValue = TypedValue()
8 | context.theme.resolveAttribute(attrId, typedValue, true)
9 | return typedValue.data
10 | }
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_minus.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/database/log/LogEntry.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.database.log
2 |
3 | import androidx.room.Entity
4 | import androidx.room.PrimaryKey
5 |
6 | @Entity(tableName = "LogEntries")
7 | data class LogEntry (
8 | @PrimaryKey(autoGenerate = true) var id: Int? = null,
9 | val epochTime: Long,
10 | val type: Int,
11 | val message: String
12 | )
13 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/compose/theme/Shape.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.compose.theme
2 |
3 | import androidx.compose.foundation.shape.RoundedCornerShape
4 | import androidx.compose.material.Shapes
5 | import androidx.compose.ui.unit.dp
6 |
7 | val Shapes = Shapes(
8 | small = RoundedCornerShape(4.dp),
9 | medium = RoundedCornerShape(4.dp),
10 | large = RoundedCornerShape(0.dp)
11 | )
--------------------------------------------------------------------------------
/automotive/src/main/res/color/button_foreground.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_chevron_back.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/liveDataApi/abrpLiveData/AbrpDataSet.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.liveDataApi.abrpLiveData
2 |
3 | data class AbrpDataSet(
4 | val stateOfCharge: Int,
5 | val power: Float,
6 | val isCharging: Boolean,
7 | val speed: Float,
8 | val isParked: Boolean,
9 | val lat: Double?,
10 | val lon: Double?,
11 | val alt: Double?,
12 | val temp: Float
13 | )
14 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/enums/PlotDimensionY.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.enums
2 |
3 | enum class PlotDimensionY {
4 | SPEED, DISTANCE, TIME, STATE_OF_CHARGE, ALTITUDE;
5 |
6 | companion object {
7 | val IndexMap = mapOf(
8 | 0 to null,
9 | 1 to SPEED,
10 | 2 to STATE_OF_CHARGE,
11 | 3 to ALTITUDE
12 | )
13 | }
14 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/color/button_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/enums/PlotDimensionX.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.enums
2 |
3 | enum class PlotDimensionX {
4 | INDEX, DISTANCE, TIME, STATE_OF_CHARGE;
5 |
6 | fun toPlotDirection(): PlotDirection {
7 | return when (this) {
8 | TIME, STATE_OF_CHARGE -> PlotDirection.LEFT_TO_RIGHT
9 | else -> PlotDirection.RIGHT_TO_LEFT
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/dataProcessor/DrivingState.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.dataProcessor
2 |
3 | object DrivingState {
4 | const val UNKNOWN = -1
5 | const val PARKED = 0
6 | const val DRIVE = 1
7 | const val CHARGE = 2
8 |
9 | val nameMap = mapOf(
10 | UNKNOWN to "UNKNOWN",
11 | PARKED to "PARKED",
12 | DRIVE to "DRIVE",
13 | CHARGE to "CHARGE"
14 | )
15 | }
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_plus.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/database/tripData/TripType.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.database.tripData
2 |
3 | object TripType {
4 | const val MANUAL = 1
5 | const val SINCE_CHARGE = 2
6 | const val AUTO = 3
7 | const val MONTH = 4
8 |
9 | val tripTypesNameMap = mapOf(
10 | MANUAL to "manual",
11 | AUTO to "auto",
12 | SINCE_CHARGE to "since charge",
13 | MONTH to "monthly"
14 | )
15 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/locationClient/LocationClient.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.locationClient
2 |
3 | import android.content.Context
4 | import android.location.Location
5 | import kotlinx.coroutines.flow.Flow
6 |
7 | interface LocationClient {
8 | fun getLocationUpdates(interval: Long, context: Context): Flow
9 | fun stopLocationUpdates()
10 | class LocationException(message: String): Exception(message)
11 | }
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_menu.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/automotive/src/legacy/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_chevron_up.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/enums/PlotMarkerType.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.enums
2 |
3 | enum class PlotMarkerType {
4 | CHARGE, PARK;
5 |
6 | fun getType(type: Int): PlotMarkerType = when (type) {
7 | 1 -> CHARGE
8 | 2 -> PARK
9 | else -> throw(Exception("Unknown marker type"))
10 | }
11 |
12 | fun getInt(type: PlotMarkerType): Int = when (type) {
13 | CHARGE -> 1
14 | PARK -> 2
15 | }
16 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/utils/SetContentViewAndTheme.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.utils
2 |
3 | import android.app.Activity
4 | import android.view.View
5 | import com.ixam97.carStatsViewer.CarStatsViewer
6 | import com.ixam97.carStatsViewer.R
7 |
8 | /*
9 | fun setContentViewAndTheme(context: Activity, view: View) {
10 | if (CarStatsViewer.appPreferences.colorTheme > 0) context.setTheme(R.style.ColorTestTheme)
11 | context.setContentView(view)
12 | }
13 | */
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/compose/Event.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.compose
2 |
3 | open class Event(private val content: T) {
4 | var wasConsumed = false
5 | private set
6 |
7 | fun peek() = content
8 |
9 | fun consume(): T? {
10 | return when (wasConsumed) {
11 | true -> null
12 | false -> {
13 | wasConsumed = true
14 | content
15 | }
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_chevron_left.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_chevron_right.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | branches:
6 | - '*'
7 |
8 | jobs:
9 | build:
10 | name: Build
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v2
15 | - name: set up JDK 17
16 | uses: actions/setup-java@v1
17 | with:
18 | java-version: 17
19 |
20 | - name: Make gradlew executable
21 | run: chmod +x ./gradlew
22 |
23 | - name: Build with Gradle
24 | run: ./gradlew build
25 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_filter_active.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_arrow_diagonal.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_upgrade.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/utils/FlowThrottle.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.utils
2 |
3 | import kotlinx.coroutines.delay
4 | import kotlinx.coroutines.flow.Flow
5 | import kotlinx.coroutines.flow.conflate
6 | import kotlinx.coroutines.flow.flow
7 |
8 | fun Flow.throttle(periodMillis: Long): Flow {
9 | if (periodMillis < 0) return this
10 | return flow {
11 | conflate().collect { value ->
12 | emit(value)
13 | delay(periodMillis)
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_arrow_back.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_filter.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/enums/PlotLineMarkerType.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.enums
2 |
3 | enum class PlotLineMarkerType(val int: Int) {
4 | BEGIN_SESSION(1), END_SESSION(2), SINGLE_SESSION(3);
5 |
6 | companion object {
7 | fun getType(type: Int?): PlotLineMarkerType? = when (type) {
8 | 1 -> BEGIN_SESSION
9 | 2 -> END_SESSION
10 | 3 -> SINGLE_SESSION
11 | else -> null // throw(Exception("Unknown marker type"))
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_battery.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_altitude.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_avg_consumption.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/utils/WatchdogState.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.utils
2 |
3 | data class WatchdogState(
4 | val locationState: Int = 0,
5 | val apiState: Map = mapOf(),
6 | val appErrorState: AppErrorState = AppErrorState()
7 | ) {
8 | companion object {
9 | const val DISABLED: Int = 0
10 | const val NOMINAL: Int = 1
11 | const val ERROR: Int = 2
12 | const val LIMITED: Int = 3
13 |
14 | data class AppErrorState(
15 | val errorMessage: String? = null
16 | )
17 | }
18 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_close.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_kill.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_notification_phone.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_upload.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_marker_charge.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/database/tripData/TripDataDatabase.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.database.tripData
2 |
3 | import androidx.room.Database
4 | import androidx.room.RoomDatabase
5 |
6 | @Database(entities =
7 | [
8 | DrivingSession::class,
9 | DrivingPoint::class,
10 | ChargingSession::class,
11 | ChargingPoint::class,
12 | DrivingSessionPointCrossRef::class,
13 | DrivingChargingCrossRef::class,
14 | SessionMarker::class
15 | ],
16 | version = 6
17 | )
18 | abstract class TripDataDatabase: RoomDatabase() {
19 |
20 | abstract fun tripDao(): TripDao
21 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_send.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/locationClient/ContextHasLocationPermission.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.locationClient
2 |
3 | import android.content.Context
4 | import android.content.pm.PackageManager
5 | import androidx.core.content.ContextCompat
6 |
7 | fun Context.hasLocationPermission(): Boolean {
8 | return ContextCompat.checkSelfPermission(
9 | this,
10 | android.Manifest.permission.ACCESS_COARSE_LOCATION
11 | ) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(
12 | this,
13 | android.Manifest.permission.ACCESS_FINE_LOCATION
14 | ) == PackageManager.PERMISSION_GRANTED
15 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_marker_park.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/automotive/src/devCarapp/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_power.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_tune.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/utils/Ticker.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.utils
2 |
3 | import kotlinx.coroutines.flow.flow
4 |
5 | object Ticker {
6 | fun tickerFlow(interval: Long) = flow {
7 | var startTime = System.currentTimeMillis()
8 | // var loops = 1L
9 |
10 | while (true) {
11 | while (true) {
12 | val currentTime = System.currentTimeMillis()
13 | if (currentTime >= (startTime + interval)) {
14 | startTime = currentTime
15 | break
16 | }
17 | }
18 | // loops ++
19 | emit(Unit)
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_altitude.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_energy_large.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_copy.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 | *.aab
5 |
6 | # Mac files
7 | .DS_Store
8 |
9 | # files for the dex VM
10 | *.dex
11 |
12 | # Java class files
13 | *.class
14 |
15 | # generated files
16 | bin/
17 | gen/
18 |
19 | # Ignore gradle files
20 | .gradle/
21 | build/
22 |
23 | # Local configuration file (sdk path, etc)
24 | local.properties
25 |
26 | # Proguard folder generated by Eclipse
27 | proguard/
28 | proguard-project.txt
29 |
30 | # Eclipse files
31 | .project
32 | .classpath
33 | .settings/
34 |
35 | # Android Studio/IDEA
36 | *.iml
37 | .idea
38 |
39 | /automotive/release/
40 | /automotive/dev/
41 | credentials.xml
42 | /automotive/stable/
43 | /automotive/debug/
44 | /.kotlin/
45 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_battery.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_mail.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_checked_checkbox.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_check.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_notification_diagram.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_temperature.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_api.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/dataProcessor/IgnitionState.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.dataProcessor
2 |
3 | import android.car.VehicleIgnitionState
4 |
5 | object IgnitionState {
6 | const val UNDEFINED = VehicleIgnitionState.UNDEFINED
7 | const val LOCK = VehicleIgnitionState.LOCK
8 | const val OFF = VehicleIgnitionState.OFF
9 | const val ACC = VehicleIgnitionState.ACC
10 | const val ON = VehicleIgnitionState.ON
11 | const val START = VehicleIgnitionState.START
12 |
13 | val nameMap = mapOf(
14 | UNDEFINED to "Undefined",
15 | LOCK to "Locked",
16 | OFF to "Off",
17 | ACC to "Accessory",
18 | ON to "On",
19 | START to "Started"
20 | )
21 |
22 | }
--------------------------------------------------------------------------------
/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/renderer/Renderer.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.carApp.renderer
2 |
3 | import android.graphics.Canvas
4 | import android.graphics.Rect
5 |
6 |
7 | interface Renderer {
8 | /**
9 | * Informs the renderer that it will receive [.renderFrame] calls.
10 | *
11 | * @param onChangeListener a runnable that will initiate a render pass in the controller
12 | */
13 | fun enable(onChangeListener: Runnable)
14 |
15 | /** Informs the renderer that it will no longer receive [.renderFrame] calls. */
16 | fun disable()
17 |
18 | /** Request that a frame should be drawn to the supplied canvas. */
19 | fun renderFrame(canvas: Canvas, visibleArea: Rect?, stableArea: Rect?)
20 | }
21 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/graphics/PlotLinePaint.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.graphics
2 |
3 | import com.ixam97.carStatsViewer.ui.plot.enums.PlotDimensionY
4 |
5 | class PlotLinePaint(
6 | private val xAxis : PlotPaint,
7 | private val yAxisNormal : PlotPaint,
8 | private val yAxisAlternative : PlotPaint,
9 | private var useYAxisAlternative: () -> Boolean
10 | ) {
11 | fun bySecondaryDimension(secondaryDimension: PlotDimensionY?) : PlotPaint {
12 | return when {
13 | secondaryDimension != null -> when {
14 | useYAxisAlternative.invoke() -> yAxisAlternative
15 | else -> yAxisNormal
16 | }
17 | else -> xAxis
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_phone.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/club_button_off.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
6 |
7 |
8 |
9 |
10 | -
11 |
13 |
14 |
15 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/dataProcessor/StaticVehicleData.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.dataProcessor
2 |
3 | import com.ixam97.carStatsViewer.utils.DistanceUnitEnum
4 |
5 | data class StaticVehicleData(
6 | val batteryCapacity: Float? = null,
7 | val vehicleMake: String? = null,
8 | val modelName: String? = null,
9 | val distanceUnit: DistanceUnitEnum? = null
10 | ) {
11 | fun isInitialized(): Boolean =
12 | isEssentialInitialized() && isOptionalInitialized()
13 |
14 | fun isEssentialInitialized(): Boolean =
15 | batteryCapacity != null
16 |
17 | fun isOptionalInitialized(): Boolean =
18 | vehicleMake != null
19 | && modelName != null
20 | && distanceUnit != null
21 | }
22 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_diagram.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_time.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_error.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_reset.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_delete.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/repository/logSubmit/LogSubmitApi.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.repository.logSubmit
2 |
3 | import okhttp3.MultipartBody
4 | import retrofit2.Response
5 | import retrofit2.http.Body
6 | import retrofit2.http.Header
7 | import retrofit2.http.Headers
8 | import retrofit2.http.POST
9 |
10 | interface LogSubmitApi {
11 |
12 | @Headers("content-type: application/json")
13 | @POST("/CSVBackend/submitLog")
14 | suspend fun submitLog(
15 | @Header("x-api-key") apiKey: String,
16 | @Body body: LogSubmitBody
17 | ): Response
18 |
19 | @POST("/CSVBackend/imageUpload")
20 | suspend fun uploadImage(
21 | @Header("x-api-key") apiKey: String,
22 | @Body body: MultipartBody
23 | ): Response
24 |
25 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/club_gradient_radial.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
10 |
11 |
12 | -
13 |
14 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_dashboard.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_history.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/utils/TimestampSynchronizer.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.utils
2 |
3 | class TimestampSynchronizer {
4 | /**
5 | * System time in millis and property timestamp in nanos associated with the same time.
6 | */
7 | private var systemTime: Long = 0
8 | private var propertyTimestamp: Long = 0
9 |
10 | fun sync(referenceSystemTime: Long, referenceTimestamp: Long) {
11 | systemTime = referenceSystemTime
12 | propertyTimestamp = referenceTimestamp
13 | }
14 |
15 | fun getSystemTimeFromNanosTimestamp(timestamp: Long): Long {
16 | if (!isSynced()) throw Exception("TimestampSynchronizer has not been synced.")
17 | val nanosDelta = (timestamp - propertyTimestamp) / 1_000_000
18 | return systemTime + nanosDelta
19 | }
20 |
21 | fun isSynced() = systemTime > 0 && propertyTimestamp > 0
22 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/club_button_on.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
6 |
7 |
10 |
11 |
12 | -
13 |
15 |
16 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_save.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_canvas.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12 | polar: # Replace with a single Polar username
13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14 | thanks_dev: # Replace with a single thanks.dev username
15 | custom: ['https://paypal.me/Ixam']
16 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/liveDataApi/http/HttpDataSet.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.liveDataApi.http
2 |
3 | import com.ixam97.carStatsViewer.database.tripData.ChargingSession
4 | import com.ixam97.carStatsViewer.database.tripData.DrivingPoint
5 |
6 | data class HttpDataSet(
7 | val apiVersion: String = "2.1",
8 | val appVersion: String,
9 | val timestamp: Long,
10 | val speed: Float?,
11 | val power: Float?,
12 | val selectedGear: String,
13 | val ignitionState: String,
14 | val chargePortConnected: Boolean?,
15 | val batteryLevel: Float?,
16 | val stateOfCharge: Float?,
17 | val ambientTemperature: Float?,
18 | val lat: Float?,
19 | val lon: Float?,
20 | val alt: Float?,
21 |
22 | // ABRP debug
23 | val abrpPackage: String? = null,
24 |
25 | val drivingPoints: List? = null,
26 | val chargingSessions: List? = null
27 | )
28 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_day.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/objects/PlotLineConfiguration.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.objects
2 |
3 | import com.ixam97.carStatsViewer.ui.plot.enums.PlotDimensionSmoothingType
4 | import com.ixam97.carStatsViewer.ui.plot.enums.PlotHighlightMethod
5 | import com.ixam97.carStatsViewer.ui.plot.enums.PlotLineLabelFormat
6 | import com.ixam97.carStatsViewer.ui.plot.enums.PlotSessionGapRendering
7 |
8 | class PlotLineConfiguration(
9 | internal val Range: PlotRange,
10 | var LabelFormat: PlotLineLabelFormat,
11 | var HighlightMethod: PlotHighlightMethod,
12 | var Unit: String,
13 | var Divider: Float = 1f,
14 | var UnitFactor: Float = 1f,
15 | var DimensionSmoothing: Float? = null,
16 | var DimensionSmoothingType: PlotDimensionSmoothingType? = null,
17 | var DimensionSmoothingHighlightMethod: PlotHighlightMethod? = null,
18 | var SessionGapRendering : PlotSessionGapRendering? = null
19 | )
--------------------------------------------------------------------------------
/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/CarStatsViewerService.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.carApp
2 |
3 | import android.content.pm.ApplicationInfo
4 | import androidx.car.app.CarAppService
5 | import androidx.car.app.Session
6 | import androidx.car.app.SessionInfo
7 | import androidx.car.app.validation.HostValidator
8 |
9 |
10 | class CarStatsViewerService : CarAppService() {
11 | override fun onCreateSession(sessionInfo: SessionInfo): Session {
12 | return CarStatsViewerSession()
13 | }
14 |
15 | override fun createHostValidator(): HostValidator {
16 | return if (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE != 0) {
17 | HostValidator.ALLOW_ALL_HOSTS_VALIDATOR
18 | } else {
19 | HostValidator.Builder(applicationContext)
20 | .addAllowedHosts(androidx.car.app.R.array.hosts_allowlist_sample)
21 | .build()
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/liveDataApi/http/TextValidator.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.liveDataApi.http
2 |
3 | import android.text.Editable
4 | import android.text.TextWatcher
5 | import android.widget.TextView
6 |
7 | // Adapted from https://stackoverflow.com/a/11838715
8 | abstract class TextValidator(private val textView: TextView) : TextWatcher {
9 | abstract fun validate(textView: TextView?, text: String?)
10 | override fun afterTextChanged(s: Editable) {
11 | val text = textView.text.toString()
12 | validate(textView, text)
13 | }
14 |
15 | override fun beforeTextChanged(
16 | s: CharSequence,
17 | start: Int,
18 | count: Int,
19 | after: Int
20 | ) { /* Don't care */
21 | }
22 |
23 | override fun onTextChanged(
24 | s: CharSequence,
25 | start: Int,
26 | before: Int,
27 | count: Int
28 | ) { /* Don't care */
29 | }
30 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/compose/screens/settings/Changelog.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.compose.screens.settings
2 |
3 | import androidx.compose.foundation.layout.fillMaxSize
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.platform.LocalContext
7 | import com.ixam97.carStatsViewer.compose.DefaultColumnScrollbar
8 | import com.ixam97.carStatsViewer.compose.components.CarRow
9 | import com.ixam97.carStatsViewer.utils.ChangeLogCreator
10 |
11 | @Composable
12 | fun Changelog() {
13 | DefaultColumnScrollbar(
14 | modifier = Modifier
15 | .fillMaxSize()
16 | ) {
17 | val changelogMap = ChangeLogCreator.createChangelog(LocalContext.current)
18 |
19 | changelogMap.forEach { (version, changes) ->
20 | CarRow(
21 | title = version,
22 | text = changes
23 | )
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/utils/GetBitmapFromVectorDrawable.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.utils
2 |
3 | import android.content.Context
4 | import android.graphics.Bitmap
5 | import android.graphics.Canvas
6 | import android.os.Build
7 | import androidx.core.content.ContextCompat
8 | import androidx.core.graphics.drawable.DrawableCompat
9 |
10 |
11 | fun getBitmapFromVectorDrawable(context: Context?, drawableId: Int): Bitmap {
12 | var drawable = ContextCompat.getDrawable(context!!, drawableId)
13 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
14 | drawable = DrawableCompat.wrap(drawable!!).mutate()
15 | }
16 |
17 | val bitmap = Bitmap.createBitmap(
18 | drawable!!.intrinsicWidth,
19 | drawable.intrinsicHeight, Bitmap.Config.ARGB_8888
20 | )
21 | val canvas = Canvas(bitmap)
22 | drawable.setBounds(0, 0, canvas.width, canvas.height)
23 | drawable.draw(canvas)
24 |
25 | return bitmap
26 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_car_app_feedback.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_location_on.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_charger.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/repository/logSubmit/LogSubmit.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.repository.logSubmit
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class LogSubmitBody(
7 | val log: Map,
8 | val userID: String,
9 | val metadata: LogMetadata
10 | ) {
11 | @Serializable
12 | data class LogMetadata(
13 | val timestamp: Long,
14 | val brand: String,
15 | val model: String,
16 | val device: String,
17 | val appInfo: String,
18 | val cpuInfo: String
19 | )
20 | }
21 |
22 | @Serializable
23 | data class AuthResponse(
24 | val authorized: String
25 | )
26 |
27 | @Serializable
28 | data class LogSubmitStatus(
29 | val status: String,
30 | val message: String?
31 | )
32 |
33 | @Serializable
34 | sealed interface LogSubmitState {
35 | @Serializable
36 | data object Success: LogSubmitState
37 |
38 | @Serializable
39 | data object Error: LogSubmitState
40 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_reset.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_connected.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/values/broadcast_actions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_link.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/res/layout/widget_fixed_switch.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
14 |
19 |
23 |
24 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_history.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_distance.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/automotive/src/main/res/values-sw700dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 101dp
4 | 60dp
5 | 75dp
6 | 50dp
7 | 74dp
8 | 31sp
9 | 27sp
10 | 20sp
11 | 45sp
12 | 500
13 | 400
14 | 32sp
15 | 2dp
16 | 70dp
17 | 60dp
18 | 100sp
19 | 30sp
20 | 15dp
21 | 2dp
22 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_car.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/utils/Watchdog.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.utils
2 |
3 | import kotlinx.coroutines.CoroutineScope
4 | import kotlinx.coroutines.Dispatchers
5 | import kotlinx.coroutines.flow.MutableSharedFlow
6 | import kotlinx.coroutines.flow.MutableStateFlow
7 | import kotlinx.coroutines.flow.asSharedFlow
8 | import kotlinx.coroutines.flow.asStateFlow
9 | import kotlinx.coroutines.launch
10 |
11 | class Watchdog() {
12 | private val _watchdogStateFlow = MutableStateFlow(WatchdogState())
13 | val watchdogStateFlow = _watchdogStateFlow.asStateFlow()
14 | private val _watchdogTriggerFlow = MutableSharedFlow(replay = 0)
15 | val watchdogTriggerFlow = _watchdogTriggerFlow.asSharedFlow()
16 |
17 | fun getCurrentWatchdogState() = watchdogStateFlow.value
18 |
19 | fun updateWatchdogState(watchdogState: WatchdogState) {
20 | _watchdogStateFlow.value = watchdogState
21 | }
22 |
23 | fun triggerWatchdog() {
24 | CoroutineScope(Dispatchers.Default).launch {
25 | _watchdogTriggerFlow.emit(Unit)
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_month.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_status.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_camera.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022-2023 Maximilian Goldschmidt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_construction.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/utils/TimeTracker.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.utils
2 |
3 | import java.util.Date
4 |
5 | /**
6 | * The TimeTracker is able to track a time span based on the Date-object.
7 | */
8 | class TimeTracker {
9 | private var startDate: Date? = null
10 | private var timeSpan: Long = 0
11 |
12 | /** Start or resume time tracking */
13 | fun start() {
14 | if (startDate == null) startDate = Date()
15 | }
16 |
17 | /** Stop time tracking */
18 | fun stop() {
19 | startDate.let {
20 | if (it != null) timeSpan += (Date().time - it.time)
21 | }
22 | startDate = null
23 | }
24 |
25 | /** Reset tracked time to zero */
26 | fun reset() {
27 | startDate = null
28 | timeSpan = 0L
29 | }
30 |
31 | /** Restore tracked time to defined base value */
32 | fun restore(pTimeSpan: Long) {
33 | timeSpan = pTimeSpan
34 | }
35 |
36 | /** returns the current tracked time in milliseconds */
37 | fun getTime(): Long {
38 | return timeSpan + (Date().time - (startDate?.time?: Date().time))
39 | }
40 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_temperature_large.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_hand.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/DevNoticeScreen.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.carApp
2 |
3 | import androidx.car.app.CarContext
4 | import androidx.car.app.Screen
5 | import androidx.car.app.model.Action
6 | import androidx.car.app.model.LongMessageTemplate
7 | import androidx.car.app.model.ParkedOnlyOnClickListener
8 | import androidx.car.app.model.Template
9 | import com.ixam97.carStatsViewer.R
10 |
11 | class DevNoticeScreen(carContext: CarContext): Screen(carContext) {
12 |
13 | override fun onGetTemplate(): Template {
14 | return LongMessageTemplate.Builder(carContext.getString(R.string.car_app_dev_notice_message)).apply {
15 | setTitle(carContext.getString(R.string.car_app_dev_notice_title))
16 | setHeaderAction(Action.APP_ICON)
17 | addAction(Action.Builder().apply {
18 | setTitle(carContext.getString(R.string.car_app_dev_notice_confirm))
19 | setFlags(Action.FLAG_PRIMARY)
20 | setOnClickListener(ParkedOnlyOnClickListener.create {
21 | screenManager.pop()
22 | })
23 | }.build())
24 | }.build()
25 | }
26 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | }
7 | }
8 |
9 | dependencyResolutionManagement {
10 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
11 | repositories {
12 | google()
13 | mavenCentral()
14 | maven { url 'https://jitpack.io' }
15 | if (useMapbox.toBoolean()) {
16 | maven {
17 |
18 | url = uri("https://api.mapbox.com/downloads/v2/releases/maven")
19 | // Do not change the username below. It should always be "mapbox" (not your username).
20 | credentials.username = "mapbox"
21 | // Use the secret token stored in local.properties (not tracked by git) as the password
22 |
23 | Properties properties = new Properties()
24 | properties.load(file("local.properties").newDataInputStream())
25 |
26 | credentials.password = properties.getProperty("MAPBOX_DOWNLOADS_TOKEN")
27 | authentication { basic(BasicAuthentication) }
28 | }
29 | }
30 | }
31 | }
32 |
33 | include ':automotive'
34 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/compose/components/CarIconButton.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.compose.components
2 |
3 | import androidx.annotation.DrawableRes
4 | import androidx.compose.foundation.layout.padding
5 | import androidx.compose.foundation.layout.size
6 | import androidx.compose.material.Icon
7 | import androidx.compose.material.IconButton
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.graphics.Color
11 | import androidx.compose.ui.res.painterResource
12 | import androidx.compose.ui.unit.dp
13 |
14 | @Composable
15 | fun CarIconButton(
16 | modifier: Modifier = Modifier,
17 | onClick: () -> Unit,
18 | @DrawableRes iconResId: Int,
19 | tint: Color = Color.White,
20 | enabled: Boolean = true
21 | ) {
22 | IconButton(
23 | enabled = enabled,
24 | modifier = modifier
25 | .padding(10.dp)
26 | .size(70.dp),
27 | onClick = onClick
28 | ) {
29 | Icon(
30 | painterResource(id = iconResId),
31 | tint = tint.copy(alpha = if (enabled) 1f else 0.3f),
32 | contentDescription = null,
33 | )
34 | }
35 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_checkmark.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_remaining_range.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/views/MultiLineRowButtonWidget.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.views
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.view.View
6 | import android.widget.LinearLayout
7 | import android.widget.TextView
8 | import com.ixam97.carStatsViewer.R
9 |
10 | class MultiLineRowButtonWidget @JvmOverloads constructor(
11 | context: Context,
12 | attrs: AttributeSet? = null,
13 | defStyleAttr: Int = 0
14 | ): LinearLayout(context, attrs, defStyleAttr) {
15 |
16 | var topText = ""
17 | set(value) {
18 | field = value
19 | init()
20 | }
21 | var bottomText = ""
22 | set(value) {
23 | field = value
24 | init()
25 | }
26 |
27 | init {
28 | init()
29 | }
30 |
31 | private fun init() {
32 | this.removeAllViews()
33 | View.inflate(context, R.layout.widget_menu_row, this)
34 | val topTextView: TextView = findViewById(R.id.row_top_text)
35 | val bottomTextView: TextView = findViewById(R.id.distance_text)
36 | topTextView.text = topText
37 | bottomTextView.text = bottomText
38 | }
39 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/liveDataApi/abrpLiveData/AppPreferencesExt.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.liveDataApi.abrpLiveData
2 |
3 | /**
4 | * This file extends the AppPreferences to contain keys used by the API implementation. The rest of
5 | * the app does not need to see them.
6 | */
7 |
8 | import com.ixam97.carStatsViewer.appPreferences.AppPreference
9 | import com.ixam97.carStatsViewer.appPreferences.AppPreferences
10 |
11 | val AppPreferences.AbrpGenericToken: AppPreference
12 | get() = AppPreference("preference_abrp_generic_token", "", sharedPref)
13 | val AppPreferences.AbrpUseApi: AppPreference
14 | get() = AppPreference("preference_abrp_use", false, sharedPref)
15 | val AppPreferences.AbrpUseLocation: AppPreference
16 | get() = AppPreference("preference_abrp_location", true, sharedPref)
17 |
18 | var AppPreferences.abrpGenericToken: String get() = AbrpGenericToken.value; set(value) {AbrpGenericToken.value = value}
19 | var AppPreferences.abrpUseApi: Boolean get() = AbrpUseApi.value; set(value) {AbrpUseApi.value = value}
20 | var AppPreferences.abrpUseLocation: Boolean get() = AbrpUseLocation.value; set(value) {AbrpUseLocation.value = value}
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_debug.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_coffee.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_location_error.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/values-sw1000dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 101dp
4 | 80dp
5 | 100dp
6 | 45dp
7 | 74dp
8 | 31sp
9 | 27sp
10 | 23sp
11 | 20sp
12 | 47sp
13 | 500
14 | 400
15 | 32sp
16 | 2dp
17 | 70dp
18 | 60dp
19 | 115sp
20 | @dimen/std_font_size
21 | 0dp
22 | 2dp
23 | 8
24 | 6
25 |
--------------------------------------------------------------------------------
/automotive/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 70dp
4 | 60dp
5 | 75dp
6 | 38dp
7 | 60dp
8 | 28sp
9 | 24sp
10 | 20sp
11 | 18sp
12 | 45sp
13 | 550
14 | 300
15 | 27sp
16 | 2dp
17 | 60dp
18 | 48dp
19 | 90sp
20 | 25sp
21 | 36dp
22 | 2dp
23 | 70dp
24 | 7
25 | 7
26 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_time_large.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_list.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_info.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_speed.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/plot/graphics/PlotMarkerPaint.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.plot.graphics
2 |
3 | import android.graphics.Color
4 | import android.graphics.Paint
5 |
6 | class PlotMarkerPaint(
7 | val Mark: Paint,
8 | val Label: Paint
9 | ){
10 | companion object {
11 | fun byColor(color : Int, textSize: Float): PlotMarkerPaint {
12 | val basePaint = basePaint(textSize)
13 |
14 | val markerPaint = Paint(basePaint)
15 | markerPaint.strokeWidth = 2f
16 | markerPaint.color = Color.argb(64, Color.red(color), Color.green(color), Color.blue(color))
17 | markerPaint.style = Paint.Style.FILL_AND_STROKE
18 |
19 | val labelPaint = Paint(basePaint)
20 | labelPaint.color = color
21 | labelPaint.textSize = textSize - 6f
22 |
23 | return PlotMarkerPaint(markerPaint, labelPaint)
24 | }
25 |
26 | fun basePaint(textSize: Float): Paint {
27 | // defines paint and canvas
28 | val basePaint = Paint()
29 | basePaint.color = Color.GRAY
30 | basePaint.isAntiAlias = true
31 | basePaint.strokeWidth = 1f
32 | basePaint.style = Paint.Style.FILL
33 | basePaint.strokeJoin = Paint.Join.ROUND
34 | basePaint.strokeCap = Paint.Cap.ROUND
35 | basePaint.textSize = textSize
36 |
37 | return basePaint
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/compose/theme/Color.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.compose.theme
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val polestarOrange = Color(0xFFD96C00)
6 | val polestarSurface = Color(0xff1f1f1f)// Color(0xff090909)
7 | val volvoBlue = Color(0xFF2F6093)
8 |
9 | val disabledTextColor = Color(0xFF757575)
10 | val disabledOverlayColor = Color(0x8A000000)
11 |
12 | val darkBackground = Color(0xFF1B1B1B)
13 | val mainBackground = Color(0xFF1F1F1F)
14 | val headerBackground = Color(0xFF282A2D)
15 | val primaryButtonGray = Color(0xFF3E4146)
16 | val primaryGray = Color(0xFF7B858A)
17 | val secondaryGray = Color(0xFFA3B1B8)
18 |
19 | val newPolestarBackground = Color(0xFF141516)
20 |
21 | val clubBlueLight = Color(0xff60bcd5)
22 | val clubBlue = Color(0xff447ea6)
23 | val clubBlueDeep = Color(0xff0c4b5d)
24 | val clubBlueDark = Color(0xff161d39)
25 | val clubVioletLight = Color(0xff8480bd)
26 | val clubViolet = Color(0xff77347b)
27 | val clubVioletDark = Color(0xff2a1037)
28 | val clubLight = Color(0xffefefef)
29 | val clubMedium = Color(0xff707a83)
30 | val clubNightVariant = Color(0xff111922)
31 | val clubNight = Color(0xff0a0f14)
32 | val clubNightDarker = Color(0xff05080C)
33 | val clubHint = Color(0xfff7ea48)
34 |
35 | val badRed = Color(0xffEB1717)
36 |
37 | val slideUpBackground = Color(0xff090909)
38 |
39 | val conConnected = Color(0xFF2595FF)
40 | val conLimited = Color(0xFFFFBF00)
41 | val conError = badRed
42 | val conUnused = disabledTextColor
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
22 | android.defaults.buildfeatures.buildconfig=true
23 | android.nonTransitiveRClass=false
24 | android.nonFinalResIds=false
25 |
26 | # Configure if Firebase and/or Mapbox should be used (Require some secrests)
27 | # See dcumentation: TODO
28 | useMapbox=false
29 | useFirebase=false
30 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/database/log/LogDao.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.database.log
2 |
3 | import androidx.room.Dao
4 | import androidx.room.Delete
5 | import androidx.room.Insert
6 | import androidx.room.Query
7 |
8 | @Dao
9 | interface LogDao {
10 |
11 | @Query("SELECT * FROM LogEntries ORDER BY epochTime ASC, id ASC")
12 | fun getAll(): List
13 |
14 | @Query("SELECT * FROM LogEntries WHERE type >= :logLevel ORDER BY epochTime ASC, id ASC")
15 | fun getLevel(logLevel: Int): List
16 |
17 | @Query("SELECT * FROM LogEntries WHERE type >= :logLevel ORDER BY epochTime DESC, id DESC LIMIT :length")
18 | // @Query("SELECT * FROM LogEntries WHERE type >= :logLevel LIMIT :length")
19 | fun getLevelAndLength(logLevel: Int, length: Int): List
20 |
21 | @Query("SELECT * FROM LogEntries WHERE epochTime BETWEEN :firstTime AND :lastTime ORDER BY epochTime ASC, id ASC")
22 | fun getTimeSpan(firstTime: Long, lastTime: Long): List
23 |
24 | fun getTimeSpan(timeSpan: Long): List {
25 | val lastTime = System.currentTimeMillis()
26 | val firstTime = lastTime - timeSpan
27 | return getTimeSpan(firstTime, lastTime)
28 | }
29 |
30 | @Insert
31 | fun insert(logEntry: LogEntry)
32 |
33 | @Delete
34 | fun delete(logEntry: LogEntry)
35 |
36 | @Query("DELETE FROM LogEntries")
37 | fun clear()
38 |
39 | @Query("DELETE FROM LogEntries WHERE epochTime < :timeLimit")
40 | fun trim(timeLimit: Long)
41 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_distance_large.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_list.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
--------------------------------------------------------------------------------
/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/ChargingSessionDetailsScreen.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.carApp
2 |
3 | import androidx.car.app.CarContext
4 | import androidx.car.app.Screen
5 | import androidx.car.app.model.Action
6 | import androidx.car.app.model.Header
7 | import androidx.car.app.model.Pane
8 | import androidx.car.app.model.PaneTemplate
9 | import androidx.car.app.model.Row
10 | import androidx.car.app.model.Template
11 | import androidx.lifecycle.DefaultLifecycleObserver
12 | import com.ixam97.carStatsViewer.database.tripData.ChargingSession
13 | import com.ixam97.carStatsViewer.utils.StringFormatters
14 | import java.util.Date
15 |
16 | class ChargingSessionDetailsScreen(
17 | carContext: CarContext,
18 | private val chargingSession: ChargingSession,
19 | private val chargingLocation: String?
20 | ): Screen(carContext), DefaultLifecycleObserver {
21 |
22 | init {
23 | lifecycle.addObserver(this)
24 | }
25 |
26 | override fun onGetTemplate(): Template {
27 | return chargingSessionDetailsTemplate()
28 | }
29 |
30 | private fun chargingSessionDetailsTemplate() = PaneTemplate.Builder(
31 | Pane.Builder().apply {
32 | addRow(Row.Builder().apply {
33 | setTitle(StringFormatters.getDateString(Date(chargingSession.start_epoch_time)))
34 | }.build())
35 | }.build()
36 | ).apply {
37 | setHeader(Header.Builder().apply {
38 | setTitle("Charging Session")
39 | setStartHeaderAction(Action.BACK)
40 | }.build())
41 | }.build()
42 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_speed.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_speed_large.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/RealTimeDataScreen.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.carApp
2 |
3 | import androidx.car.app.CarContext
4 | import androidx.car.app.Screen
5 | import androidx.car.app.model.Template
6 | import androidx.lifecycle.DefaultLifecycleObserver
7 | import androidx.lifecycle.LifecycleOwner
8 | import androidx.lifecycle.lifecycleScope
9 | import com.ixam97.carStatsViewer.CarStatsViewer
10 | import com.ixam97.carStatsViewer.utils.throttle
11 | import kotlinx.coroutines.launch
12 |
13 | class RealTimeDataScreen(
14 | carContext: CarContext,
15 | val session: CarStatsViewerSession
16 | ): Screen(carContext), DefaultLifecycleObserver {
17 |
18 | private val realTimeDataTemplate = RealTimeDataTemplate(
19 | carContext,
20 | session,
21 | backButton = true,
22 | navigationOnly = false
23 | ) {
24 | invalidate()
25 | }
26 |
27 | init {
28 | lifecycle.addObserver(this)
29 | lifecycleScope.launch {
30 | CarStatsViewer.dataProcessor.realTimeDataFlow.throttle(500).collect {
31 | if (session.carDataSurfaceCallback.isEnabled()) session.carDataSurfaceCallback.requestRenderFrame()
32 | }
33 | }
34 | }
35 |
36 | override fun onCreate(owner: LifecycleOwner) {
37 | session.carDataSurfaceCallback.resume()
38 | }
39 |
40 | override fun onGetTemplate(): Template {
41 | return realTimeDataTemplate.getTemplate()
42 | }
43 |
44 | override fun onDestroy(owner: LifecycleOwner) {
45 | session.carDataSurfaceCallback.pause()
46 | }
47 | }
--------------------------------------------------------------------------------
/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/ConfirmResetScreen.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.carApp
2 |
3 | import androidx.car.app.CarContext
4 | import androidx.car.app.Screen
5 | import androidx.car.app.model.Action
6 | import androidx.car.app.model.CarIcon
7 | import androidx.car.app.model.MessageTemplate
8 | import androidx.car.app.model.Template
9 | import androidx.core.graphics.drawable.IconCompat
10 | import com.ixam97.carStatsViewer.R
11 |
12 | class ConfirmResetScreen(carContext: CarContext) : Screen(carContext) {
13 |
14 | override fun onGetTemplate(): Template {
15 | return dialogTemplate()
16 | }
17 |
18 | private fun dialogTemplate() = MessageTemplate.Builder(
19 | carContext.getString(R.string.dialog_reset_message)
20 | ).apply {
21 | setHeaderAction(Action.BACK)
22 | setTitle(carContext.getString(R.string.dialog_reset_title))
23 | setIcon(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_reset)).build())
24 | addAction(Action.Builder().apply {
25 | setTitle(carContext.getString(R.string.dialog_reset_confirm))
26 | setFlags(Action.FLAG_PRIMARY)
27 | setOnClickListener {
28 | setResult(true)
29 | screenManager.pop()
30 | }
31 | }.build())
32 | addAction(Action.Builder().apply {
33 | setTitle(carContext.getString(R.string.dialog_reset_cancel))
34 | setOnClickListener {
35 | setResult(false)
36 | screenManager.pop()
37 | }
38 | }.build())
39 | }.build()
40 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/club_gradient.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
10 |
11 |
12 |
18 |
21 |
24 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/carPropertiesClient/CarProperty.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.carPropertiesClient
2 |
3 | class CarProperty(val propertyId: Int) {
4 |
5 | private val startupTimestamp = System.nanoTime()
6 | private var lastTimestamp: Long = startupTimestamp
7 |
8 | /** Value of the Vehicle */
9 | var value: Any? = null
10 | internal set(value) {
11 | lastValue = field
12 | field = value
13 | }
14 |
15 | var lastValue: Any? = null
16 | internal set
17 |
18 | /** Timestamp of the last time the value was changed in nanoseconds */
19 | var timestamp: Long = startupTimestamp
20 | internal set(value) {
21 | lastTimestamp = field
22 | field = value
23 | }
24 |
25 | /** Time difference between value changes in nanoseconds */
26 | val timeDelta: Long get() {
27 | if (lastTimestamp == 0L || lastTimestamp < startupTimestamp) return 0L
28 | return timestamp - lastTimestamp
29 | }
30 |
31 | /** Returns true if the value difference is null, therefore the value is the initial value */
32 | val isInitialValue: Boolean get() = (valueDelta == null)
33 |
34 | /** Value difference since last value change */
35 | val valueDelta: Any?
36 | get() {
37 | value.let {
38 | if (it == null || lastValue == null) return null
39 | if (it is Float) return (it - lastValue as Float)
40 | if (it is Int) return (it - lastValue as Int)
41 | if (it is Boolean) return !(lastValue as Boolean)
42 | }
43 | return null
44 | }
45 | }
--------------------------------------------------------------------------------
/automotive/src/carapp/res/drawable/ic_car_app_settings.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/compose/ComposeSettingsActivity.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.compose
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import androidx.compose.runtime.collectAsState
7 | import androidx.lifecycle.viewmodel.compose.viewModel
8 | import com.ixam97.carStatsViewer.R
9 | import com.ixam97.carStatsViewer.compose.screens.SettingsScreen
10 | import com.ixam97.carStatsViewer.compose.theme.CarTheme
11 |
12 | class ComposeSettingsActivity: ComponentActivity() {
13 |
14 | private var reinitSates: () -> Unit = {}
15 |
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | super.onCreate(savedInstanceState)
18 | setTheme(R.style.AppTheme)
19 |
20 | val targetScreen: String? = if (intent.hasExtra("TargetRoute")) {
21 | intent.getStringExtra("TargetRoute")
22 | } else {
23 | null
24 | }
25 |
26 | setContent {
27 | val settingsViewModel: SettingsViewModel = viewModel()
28 | val themeSetting = settingsViewModel.themeSettingStateFLow.collectAsState()
29 |
30 | reinitSates = { settingsViewModel.initStates() }
31 |
32 | settingsViewModel.finishActivityLiveData.observe(this) {
33 | if (it.consume() == true) finish()
34 | }
35 |
36 | val brand = brandSelector(themeSetting.value)
37 |
38 | CarTheme(brand) {
39 | SettingsScreen(viewModel = settingsViewModel, targetRoute = targetScreen)
40 | }
41 | }
42 | }
43 |
44 | override fun onResume() {
45 | reinitSates.invoke()
46 | super.onResume()
47 | }
48 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_debug.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/club_thumb_off.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
10 |
11 |
12 |
18 |
21 |
24 |
25 |
26 |
27 |
28 |
29 | -
30 |
32 |
33 |
34 |
35 |
36 | -
37 |
38 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/club_thumb_on.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
10 |
11 |
12 |
18 |
21 |
24 |
25 |
26 |
27 |
28 |
29 | -
30 |
32 |
33 |
34 |
35 |
36 | -
37 |
38 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/appPreferences/AppPreference.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.appPreferences
2 |
3 | import android.content.SharedPreferences
4 | import com.ixam97.carStatsViewer.ui.plot.enums.PlotDimensionX
5 | import com.ixam97.carStatsViewer.utils.DistanceUnitEnum
6 |
7 | class AppPreference(
8 | private val key: String,
9 | private val default: T,
10 | private val sharedPref: SharedPreferences) {
11 |
12 | var value: T
13 | get() {
14 | return when (default) {
15 | is Boolean -> sharedPref.getBoolean(key, default) as T
16 | is Int -> sharedPref.getInt(key, default) as T
17 | is Long -> sharedPref.getLong(key, default) as T
18 | is String -> sharedPref.getString(key, default) as T
19 | is PlotDimensionX -> PlotDimensionX.valueOf(sharedPref.getString(key, default.name)!!) as T
20 | is DistanceUnitEnum -> DistanceUnitEnum.valueOf(sharedPref.getString(key, default.name)!!) as T
21 | else -> default
22 | }
23 | }
24 | set(value) {
25 | when (default) {
26 | is Boolean -> sharedPref.edit().putBoolean(key, value as Boolean).apply()
27 | is Int -> sharedPref.edit().putInt(key, value as Int).apply()
28 | is Long -> sharedPref.edit().putLong(key, value as Long).apply()
29 | is String -> sharedPref.edit().putString(key, value as String).apply()
30 | is PlotDimensionX -> sharedPref.edit().putString(key, (value as PlotDimensionX).name).apply()
31 | is DistanceUnitEnum ->sharedPref.edit().putString(key, (value as DistanceUnitEnum).name).apply()
32 | //else ->
33 | }
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_help.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/utils/Utils.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.carApp.utils
2 |
3 | import android.graphics.Bitmap
4 | import androidx.annotation.DrawableRes
5 | import androidx.car.app.CarContext
6 | import androidx.car.app.constraints.ConstraintManager
7 | import androidx.car.app.model.CarIcon
8 | import androidx.core.graphics.drawable.IconCompat
9 | import com.ixam97.carStatsViewer.R
10 |
11 | fun Bitmap.asCarIcon(): CarIcon = CarIcon.Builder(IconCompat.createWithBitmap(this)).build()
12 |
13 | fun CarContext.carIconFromRes(@DrawableRes resID: Int) = CarIcon.Builder(IconCompat.createWithResource(this, resID)).build()
14 |
15 | val CarContext.constraintManager
16 | get() = getCarService(CarContext.CONSTRAINT_SERVICE) as ConstraintManager
17 |
18 | fun CarContext.getContentLimit(id: Int) = if (carAppApiLevel >= 2) {
19 | constraintManager.getContentLimit(id)
20 | } else {
21 | when (id) {
22 | ConstraintManager.CONTENT_LIMIT_TYPE_GRID -> 6
23 | ConstraintManager.CONTENT_LIMIT_TYPE_LIST -> 6
24 | ConstraintManager.CONTENT_LIMIT_TYPE_PANE -> 4
25 | ConstraintManager.CONTENT_LIMIT_TYPE_PLACE_LIST -> 6
26 | ConstraintManager.CONTENT_LIMIT_TYPE_ROUTE_LIST -> 3
27 | else -> throw IllegalArgumentException("unknown limit ID")
28 | }
29 | }
30 |
31 | fun manualTripIcon(carContext: CarContext) = CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_hand)).build()
32 | fun sinceChargeTripIcon(carContext: CarContext) = CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_charger)).build()
33 | fun autoTripIcon(carContext: CarContext) = CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_day)).build()
34 | fun monthTripIcon(carContext: CarContext) = CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_month)).build()
--------------------------------------------------------------------------------
/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/ConfirmDeleteTripScreen.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.carApp
2 |
3 | import androidx.car.app.CarContext
4 | import androidx.car.app.Screen
5 | import androidx.car.app.model.Action
6 | import androidx.car.app.model.Header
7 | import androidx.car.app.model.MessageTemplate
8 | import androidx.car.app.model.Pane
9 | import androidx.car.app.model.PaneTemplate
10 | import androidx.car.app.model.Template
11 | import androidx.lifecycle.DefaultLifecycleObserver
12 | import com.ixam97.carStatsViewer.R
13 | import com.ixam97.carStatsViewer.carApp.utils.carIconFromRes
14 |
15 | class ConfirmDeleteTripScreen(carContext: CarContext):
16 | Screen(carContext), DefaultLifecycleObserver
17 | {
18 | init {
19 | lifecycle.addObserver(this)
20 | }
21 |
22 | override fun onGetTemplate(): Template {
23 | return confirmDeleteTripTemplate()
24 | }
25 |
26 | private fun confirmDeleteTripTemplate() = MessageTemplate.Builder(
27 | carContext.getString(R.string.history_dialog_delete_message)
28 | ).apply {
29 | setHeader(Header.Builder().apply {
30 | setTitle(carContext.getString(R.string.history_dialog_delete_title))
31 | }.build())
32 | setIcon(carContext.carIconFromRes(R.drawable.ic_delete))
33 | addAction(Action.Builder().apply {
34 | setTitle(carContext.getString(R.string.history_dialog_delete_confirm))
35 | setFlags(Action.FLAG_PRIMARY)
36 | setOnClickListener {
37 | setResult(true)
38 | screenManager.pop()
39 | }
40 | }.build())
41 | addAction(Action.Builder().apply {
42 | setTitle(carContext.getString(R.string.dialog_reset_cancel))
43 | setOnClickListener {
44 | setResult(false)
45 | screenManager.pop()
46 | }
47 | }.build())
48 | }.build()
49 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/compose/screens/settings/GeneralSettings.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.compose.screens.settings
2 |
3 | import androidx.compose.foundation.layout.fillMaxSize
4 | import androidx.compose.foundation.layout.padding
5 | import androidx.compose.material.Divider
6 | import androidx.compose.material.Text
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.ui.Modifier
9 | import androidx.compose.ui.res.stringResource
10 | import androidx.compose.ui.unit.dp
11 | import com.ixam97.carStatsViewer.R
12 | import com.ixam97.carStatsViewer.compose.DefaultColumnScrollbar
13 | import com.ixam97.carStatsViewer.compose.SettingsViewModel
14 | import com.ixam97.carStatsViewer.compose.components.CarSwitchRow
15 |
16 | @Composable
17 | fun GeneralSettings(
18 | viewModel: SettingsViewModel
19 | ) {
20 | DefaultColumnScrollbar(
21 | modifier = Modifier
22 | .fillMaxSize()
23 | ) {
24 | CarSwitchRow(
25 | switchState = viewModel.settingsState.autoAppStart,
26 | onClick = { viewModel.setAutoAppStart(it) }
27 | ) {
28 | Text(text = stringResource(id = R.string.settings_autostart))
29 | }
30 | Divider(Modifier.padding(horizontal = 20.dp))
31 | CarSwitchRow(
32 | switchState = viewModel.settingsState.phoneNotification,
33 | onClick = { viewModel.setPhoneNotification(it) }
34 | ) {
35 | Text(text = stringResource(id = R.string.settings_phone_reminder))
36 | }
37 | Divider(Modifier.padding(horizontal = 20.dp))
38 | CarSwitchRow(
39 | switchState = viewModel.settingsState.detailedNotifications,
40 | onClick = { viewModel.setDetailedNotifications(it) }
41 | ) {
42 | Text(text = stringResource(id = R.string.settings_notifications))
43 | }
44 | Divider(Modifier.padding(horizontal = 20.dp))
45 | }
46 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/map/MapboxInterface.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.map
2 |
3 | import android.location.Geocoder
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.material.Text
6 | import androidx.compose.runtime.Composable
7 | import androidx.compose.ui.Alignment
8 | import androidx.compose.ui.Modifier
9 | import com.ixam97.carStatsViewer.CarStatsViewer
10 | import com.ixam97.carStatsViewer.database.tripData.DrivingSession
11 | import com.ixam97.carStatsViewer.utils.InAppLogger
12 | import java.util.Locale
13 |
14 | interface MapboxInterface {
15 | fun isDummy(): Boolean
16 |
17 | @Composable
18 | fun MapBoxContainer(
19 | modifier: Modifier,
20 | trip: DrivingSession?,
21 | chargingMarkerOnClick: ((id: Long) -> Unit)
22 | ) {
23 | Box (
24 | modifier = modifier,
25 | contentAlignment = Alignment.Center
26 | ) {
27 | Text("No Mapbox API configured!")
28 | }
29 |
30 | }
31 |
32 | // Using the built in Android Geocoder
33 | suspend fun getAddress(lon: Double, lat: Double): String {
34 | if (!Geocoder.isPresent()) return ("%.6f, %.6f".format(lat, lon))
35 |
36 | val geocoder = Geocoder(CarStatsViewer.appContext, Locale.getDefault())
37 | val result =
38 | try {
39 | // Deprecated with API level 33, but not available in lower API levels.
40 | // Therefore suspend fun. TODO: Implement new function for API 33+
41 | geocoder.getFromLocation(lat, lon, 1)
42 | } catch (e: Throwable) {
43 | InAppLogger.e("[Geo] Unable to get address from geocoder:")
44 | InAppLogger.e(e.stackTraceToString())
45 | null
46 | }
47 |
48 | return if (!result.isNullOrEmpty()) {
49 | result[0].getAddressLine(0)
50 | } else {
51 | ("%.6f, %.6f".format(lat, lon))
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/compose/components/CarSwitchRow.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.compose.components
2 |
3 | import androidx.compose.foundation.clickable
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.foundation.layout.Row
6 | import androidx.compose.foundation.layout.Spacer
7 | import androidx.compose.foundation.layout.heightIn
8 | import androidx.compose.foundation.layout.padding
9 | import androidx.compose.foundation.layout.size
10 | import androidx.compose.foundation.layout.widthIn
11 | import androidx.compose.material.Switch
12 | import androidx.compose.runtime.Composable
13 | import androidx.compose.ui.Alignment
14 | import androidx.compose.ui.Modifier
15 | import androidx.compose.ui.graphics.TransformOrigin
16 | import androidx.compose.ui.graphics.graphicsLayer
17 | import androidx.compose.ui.unit.dp
18 |
19 | @Composable
20 | fun CarSwitchRow(
21 | enabled: Boolean = true,
22 | switchState: Boolean,
23 | onClick: (newState: Boolean) -> Unit,
24 | content: @Composable (enabled: Boolean) -> Unit
25 | ) {
26 | Row(
27 | modifier = Modifier
28 | .heightIn(min = 100.dp)
29 | .clickable(enabled = enabled) { onClick(!switchState) }
30 | .padding(horizontal = 30.dp),
31 | verticalAlignment = Alignment.CenterVertically
32 | ) {
33 | content(enabled)
34 | Spacer(modifier = Modifier.weight(1f).widthIn(min = 20.dp))
35 | Box(
36 | modifier = Modifier.size(80.dp),
37 | contentAlignment = Alignment.Center
38 | ) {
39 | Switch(
40 | modifier = Modifier
41 | // .scale(2f)
42 | .graphicsLayer(
43 | transformOrigin = TransformOrigin(1f,.5f),
44 | scaleX = 2f,
45 | scaleY = 2f),
46 | checked = switchState,
47 | onCheckedChange = null,
48 | enabled = enabled
49 | )
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_performance.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/automotive/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_webhook.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/compose/ComposeTripDetailsActivity.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.compose
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import androidx.lifecycle.viewmodel.compose.viewModel
7 | import com.ixam97.carStatsViewer.CarStatsViewer
8 | import com.ixam97.carStatsViewer.R
9 | import com.ixam97.carStatsViewer.compose.screens.TripDetailsPortraitScreen
10 | import com.ixam97.carStatsViewer.compose.theme.CarTheme
11 |
12 | class ComposeTripDetailsActivity: ComponentActivity() {
13 | override fun onCreate(savedInstanceState: Bundle?) {
14 | super.onCreate(savedInstanceState)
15 | setTheme(R.style.AppTheme)
16 |
17 | if (!intent.hasExtra("SessionId")) {
18 | finish()
19 | } else {
20 | val sessionId = intent.getLongExtra("SessionId", 0)
21 | setContent {
22 | val viewModel: TripDetailsViewModel = viewModel()
23 |
24 | // val tripDetailsState = viewModel.tripDetailsState
25 |
26 | val brand = brandSelector(CarStatsViewer.appPreferences.colorTheme)
27 |
28 | CarTheme(brand) {
29 | TripDetailsPortraitScreen(
30 | viewModel = viewModel,
31 | sessionId = sessionId
32 | )
33 | /*
34 | if (tripDetailsState.drivingSession != null) {
35 | TripDetailsPortraitScreen(
36 | viewModel = viewModel
37 | )
38 | } else {
39 | viewModel.loadDrivingSession(sessionId)
40 | Box(
41 | modifier = Modifier
42 | .fillMaxSize(),
43 | contentAlignment = Alignment.Center
44 | ) {
45 | CircularProgressIndicator()
46 | }
47 | }
48 |
49 | */
50 | }
51 | }
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/layout/activity_permissions.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
22 |
23 |
35 |
36 |
45 |
--------------------------------------------------------------------------------
/automotive/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
30 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/compose/screens/settings/PrivacySettings.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.compose.screens.settings
2 |
3 | import androidx.compose.foundation.layout.fillMaxSize
4 | import androidx.compose.foundation.layout.padding
5 | import androidx.compose.material.Divider
6 | import androidx.compose.material.Text
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.ui.Modifier
9 | import androidx.compose.ui.platform.LocalContext
10 | import androidx.compose.ui.res.stringResource
11 | import androidx.compose.ui.unit.dp
12 | import com.ixam97.carStatsViewer.R
13 | import com.ixam97.carStatsViewer.compose.DefaultColumnScrollbar
14 | import com.ixam97.carStatsViewer.compose.SettingsViewModel
15 | import com.ixam97.carStatsViewer.compose.components.CarRow
16 | import com.ixam97.carStatsViewer.compose.components.CarSwitchRow
17 |
18 | @Composable
19 | fun PrivacySettings(
20 | viewModel: SettingsViewModel
21 | ) {
22 | val context = LocalContext.current
23 | DefaultColumnScrollbar(
24 | modifier = Modifier
25 | .fillMaxSize()
26 | ) {
27 | CarSwitchRow(
28 | switchState = viewModel.settingsState.locationTracking,
29 | onClick = { viewModel.setLocationTracking(it) }
30 | ) {
31 | Text(text = stringResource(id = R.string.settings_use_location))
32 | }
33 | Divider(Modifier.padding(horizontal = 20.dp))
34 | if (stringResource(R.string.useFirebase) == "true") {
35 | CarSwitchRow(
36 | switchState = viewModel.settingsState.analytics,
37 | onClick = { viewModel.setAnalytics(it) }
38 | ) {
39 | Text(text = stringResource(R.string.settings_analytics))
40 | }
41 | } else {
42 | CarRow(title = stringResource(R.string.settings_firebase_note))
43 | }
44 | Divider(modifier = Modifier.padding(horizontal = 24.dp))
45 | CarRow(
46 | title = stringResource(R.string.settings_privacy),
47 | browsable = true,
48 | external = true,
49 | onClick = { viewModel.openPrivacyLink(context) }
50 | )
51 | }
52 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/liveDataApi/http/AppPreferencesExt.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.liveDataApi.http
2 |
3 | /**
4 | * This file extends the AppPreferences to contain keys used by the API implementation. The rest of
5 | * the app does not need to see them.
6 | */
7 |
8 | import com.ixam97.carStatsViewer.appPreferences.AppPreference
9 | import com.ixam97.carStatsViewer.appPreferences.AppPreferences
10 |
11 | val AppPreferences.HTTPLiveDataURL: AppPreference
12 | get() = AppPreference("preference_http_live_data_url", "", sharedPref)
13 |
14 | val AppPreferences.HTTPLiveDataUsername: AppPreference
15 | get() = AppPreference("preference_http_live_data_username", "", sharedPref)
16 |
17 | val AppPreferences.HTTPLiveDataPassword: AppPreference
18 | get() = AppPreference("preference_http_live_data_password", "", sharedPref)
19 |
20 | val AppPreferences.HTTPLiveDataEnabled: AppPreference
21 | get() = AppPreference("preference_http_live_data_enables", false, sharedPref)
22 |
23 | val AppPreferences.HTTPLiveDataLocation: AppPreference
24 | get() = AppPreference("preference_http_live_data_location", true, sharedPref)
25 |
26 | val AppPreferences.HTTPLiveDataSendABRPDataset: AppPreference
27 | get() = AppPreference("preference_http_live_data_abrp", false, sharedPref)
28 |
29 | var AppPreferences.httpLiveDataURL: String get() = HTTPLiveDataURL.value; set(value) {HTTPLiveDataURL.value = value}
30 | var AppPreferences.httpLiveDataUsername: String get() = HTTPLiveDataUsername.value; set(value) {HTTPLiveDataUsername.value = value}
31 | var AppPreferences.httpLiveDataPassword: String get() = HTTPLiveDataPassword.value; set(value) {HTTPLiveDataPassword.value = value}
32 | var AppPreferences.httpLiveDataEnabled: Boolean get() = HTTPLiveDataEnabled.value; set(value) {HTTPLiveDataEnabled.value = value}
33 | var AppPreferences.httpLiveDataLocation: Boolean get() = HTTPLiveDataLocation.value; set(value) {HTTPLiveDataLocation.value = value}
34 | var AppPreferences.httpLiveDataSendABRPDataset: Boolean get() = HTTPLiveDataSendABRPDataset.value; set(value) {HTTPLiveDataSendABRPDataset.value = value}
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/utils/ChangeLogCreator.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.utils
2 |
3 | import android.content.Context
4 | import com.ixam97.carStatsViewer.R
5 |
6 | object ChangeLogCreator {
7 |
8 | private val versionRegex = Regex("\\[V]\\((.*)\\)")
9 |
10 | fun createChangelog(context: Context): Map {
11 |
12 | val changesList = context.resources.getStringArray(R.array.changes).toMutableList()
13 | val pendingChangesList = context.resources.getStringArray(R.array.pending_changes).toMutableList()
14 |
15 | pendingChangesList.toList().forEachIndexed { index, change ->
16 | if (change.contains(versionRegex)) {
17 | val match = versionRegex.find(change)!!.destructured.toList()[0]
18 | pendingChangesList[index] = "[V]($match (Pre-Release))"
19 | }
20 | }
21 |
22 | val versionsMap = mutableMapOf()
23 |
24 | var currentTitle = ""
25 | var currentChanges = ""
26 |
27 | changesList.addAll(pendingChangesList)
28 |
29 | changesList.reversed().forEachIndexed { index, change ->
30 | if (change.contains(versionRegex)) {
31 | if (index > 0) {
32 | versionsMap[currentTitle] = currentChanges
33 | }
34 | versionRegex.find(change)?.let {
35 | val destructedChange = it.destructured.toList()
36 | currentTitle = if (destructedChange.isNotEmpty()) it.destructured.toList()[0] else "UNKNOWN"
37 | }
38 | currentChanges = ""
39 | } else {
40 | if (currentChanges.isNotEmpty()) currentChanges += "\n"
41 | currentChanges += "● $change"
42 | if (index >= changesList.size -1) {
43 | versionsMap[currentTitle] = currentChanges
44 | }
45 | }
46 | }
47 |
48 | return versionsMap
49 | }
50 |
51 | private fun String.toPreReleaseVersion(): String {
52 | val original = this
53 |
54 | var preReleaseVersion: String = ""
55 |
56 | return preReleaseVersion
57 | }
58 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/dataProcessor/RealTimeData.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.dataProcessor
2 |
3 | import android.car.VehicleGear
4 | import android.car.VehicleIgnitionState
5 | import android.os.Build
6 |
7 | data class RealTimeData(
8 | val speed: Float? = null,
9 | val power: Float? = null,
10 | val selectedGear: Int? = null,
11 | val ignitionState: Int? = null,
12 | val chargePortConnected: Boolean? = null,
13 | val batteryLevel: Float? = null,
14 | val stateOfCharge: Float? = null,
15 | val ambientTemperature: Float? = null,
16 | val lat: Float? = null,
17 | val lon: Float? = null,
18 | val alt: Float? = null
19 | ) {
20 | val drivingState: Int get() = getDriveState()
21 | val instConsumption: Float? get() = getInstCons()
22 | val optimizeDistraction: Boolean get() = speed != null && speed > 0.0
23 |
24 | fun isInitialized(): Boolean {
25 | return isEssentialInitialized() && isOptionalInitialized()
26 | }
27 |
28 | fun isOptionalInitialized(): Boolean {
29 | return ambientTemperature != null
30 | }
31 |
32 | fun isEssentialInitialized(): Boolean {
33 | return speed != null
34 | && (power != null || Build.DEVICE == "moose" || Build.DEVICE == "ihu_emulator")
35 | && selectedGear != null
36 | && ignitionState != null
37 | && chargePortConnected != null
38 | && batteryLevel != null
39 | && stateOfCharge != null
40 | }
41 |
42 | private fun getDriveState(): Int {
43 | return if (chargePortConnected == true) DrivingState.CHARGE
44 | else if (ignitionState == VehicleIgnitionState.START || (ignitionState == VehicleIgnitionState.ON && selectedGear == VehicleGear.GEAR_DRIVE)) DrivingState.DRIVE
45 | else if (ignitionState != VehicleIgnitionState.UNDEFINED && ignitionState != null) DrivingState.PARKED
46 | else DrivingState.UNKNOWN
47 | }
48 |
49 | private fun getInstCons(): Float? {
50 | if (power == null || speed == null) return null
51 | val instCons = (power / 1_000f) / (speed * 3.6f)
52 | return if (instCons.isFinite()) instCons else null
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/compose/screens/MapboxScreen.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.compose.screens
2 |
3 | import androidx.compose.foundation.layout.Column
4 | import androidx.compose.foundation.layout.fillMaxWidth
5 | import androidx.compose.foundation.layout.padding
6 | import androidx.compose.material.Text
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.runtime.LaunchedEffect
9 | import androidx.compose.runtime.getValue
10 | import androidx.compose.runtime.mutableStateOf
11 | import androidx.compose.runtime.remember
12 | import androidx.compose.runtime.setValue
13 | import androidx.compose.ui.Modifier
14 | import androidx.compose.ui.unit.dp
15 | import com.ixam97.carStatsViewer.CarStatsViewer
16 | import com.ixam97.carStatsViewer.map.Mapbox
17 |
18 | @Composable
19 | fun MapboxScreen() {
20 |
21 | val trip = CarStatsViewer.dataProcessor.selectedSessionData
22 |
23 | var startAddr by remember { mutableStateOf("Unknown") }
24 | var destAddr by remember { mutableStateOf("Unknown") }
25 |
26 | Column {
27 | Mapbox.MapBoxContainer(
28 | modifier = Modifier
29 | .fillMaxWidth()
30 | .weight(1f),
31 | trip = trip,
32 | chargingMarkerOnClick = {}
33 | )
34 | Text(
35 | modifier = Modifier.padding(vertical = 10.dp, horizontal = 25.dp),
36 | text = "Start: $startAddr"
37 | )
38 | Text(
39 | modifier = Modifier.padding(vertical = 10.dp, horizontal = 25.dp),
40 | text = "Destination: $destAddr"
41 | )
42 | }
43 |
44 | LaunchedEffect(Unit) {
45 | if (trip != null) {
46 | if (!trip.drivingPoints.isNullOrEmpty()) {
47 | val coordinates = trip.drivingPoints!!.filter { it.lat != null }
48 | startAddr = Mapbox.getAddress(
49 | coordinates.first().lon!!.toDouble(),
50 | coordinates.first().lat!!.toDouble()
51 | )
52 | destAddr = Mapbox.getAddress(
53 | coordinates.last().lon!!.toDouble(),
54 | coordinates.last().lat!!.toDouble()
55 | )
56 | }
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/automotive/src/main/java/com/ixam97/carStatsViewer/ui/views/FixedSwitchWidget.kt:
--------------------------------------------------------------------------------
1 | package com.ixam97.carStatsViewer.ui.views
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.view.View
6 | import android.widget.LinearLayout
7 | import android.widget.Switch
8 | import android.widget.TextView
9 | import com.ixam97.carStatsViewer.R
10 |
11 | class FixedSwitchWidget @JvmOverloads constructor(
12 | context: Context,
13 | attrs: AttributeSet? = null,
14 | defStyleAttr: Int = 0
15 | ): LinearLayout(context, attrs, defStyleAttr) {
16 |
17 | private var clickListener: ClickListener? = null
18 |
19 | private var label: String = ""
20 |
21 | private lateinit var container: View
22 | private lateinit var switch: Switch
23 | private lateinit var labelView: TextView
24 |
25 | init {
26 | val attributes = context.obtainStyledAttributes(attrs, R.styleable.FixedSwitchWidget)
27 | try {
28 | label = attributes.getString(R.styleable.FixedSwitchWidget_text)?:""
29 | } finally {
30 | attributes.recycle()
31 | }
32 | init()
33 | }
34 |
35 | private fun init() {
36 | this.removeAllViews()
37 | View.inflate(context, R.layout.widget_fixed_switch, this)
38 |
39 | labelView = findViewById(R.id.switch_label)
40 | container = findViewById(R.id.container)
41 | switch = findViewById(R.id.switch_switch)
42 |
43 | labelView.text = label
44 |
45 | container.setOnClickListener {
46 | switch.isChecked = !switch.isChecked
47 | clickListener?.onClick()
48 | }
49 |
50 | switch.setOnClickListener {
51 | clickListener?.onClick()
52 | }
53 | }
54 |
55 | var isChecked
56 | get() = switch.isChecked
57 | set(value) {switch.isChecked = value}
58 |
59 | var text: String
60 | get() = labelView.text.toString()
61 | set(value) {
62 | labelView.text = value
63 | label = value
64 | }
65 |
66 | fun interface ClickListener {
67 | fun onClick()
68 | }
69 |
70 | fun setSwitchClickListener(listener: ClickListener?) {
71 | clickListener = listener
72 | }
73 |
74 | }
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_trip_start.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
9 |
12 |
13 |
14 |
15 | -
16 |
21 |
24 |
25 |
26 | -
27 |
32 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/automotive/src/main/res/layout/widget_multi_select.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
14 |
21 |
28 |
35 |
43 |
44 |
45 |
51 |
--------------------------------------------------------------------------------
/automotive/src/main/res/values-w877dp/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
21 |
31 |
41 |
--------------------------------------------------------------------------------
/automotive/src/main/res/drawable/ic_trip_charging_location.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
9 |
12 |
13 |
14 |
15 | -
16 |
21 |
24 |
25 |
26 | -
27 |
33 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------