-
Notifications
You must be signed in to change notification settings - Fork 319
initial commit of the new telemetry handler #2445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
libnavigation-base/src/main/java/com/mapbox/navigation/base/exceptions/NavigationException.kt
Outdated
Show resolved
Hide resolved
libnavigation-core/src/main/java/com/mapbox/navigation/core/telemetry/PhoneState.kt
Outdated
Show resolved
Hide resolved
| import android.location.Location | ||
| import com.google.gson.Gson | ||
|
|
||
| internal enum class FeedbackType(val feedbackType: String) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is never used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be used once UserFeedback events are posted to Telemetry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 removed
...gation-core/src/main/java/com/mapbox/navigation/core/telemetry/TelemetryEventUserFeedback.kt
Outdated
Show resolved
Hide resolved
libnavigation-core/src/main/java/com/mapbox/navigation/core/telemetry/audio/AudioTypeChain.kt
Outdated
Show resolved
Hide resolved
...avigation-core/src/main/java/com/mapbox/navigation/core/telemetry/audio/AudioTypeResolver.kt
Outdated
Show resolved
Hide resolved
RingerJK
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good 👍 need some changes
...igation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt
Outdated
Show resolved
Hide resolved
...igation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt
Outdated
Show resolved
Hide resolved
...igation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt
Outdated
Show resolved
Hide resolved
| import com.mapbox.navigation.core.telemetry.audio.AudioTypeChain | ||
| import kotlin.math.floor | ||
|
|
||
| internal object NavigationUtils { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also would be great have it as extensions
libnavigation-core/src/main/java/com/mapbox/navigation/core/telemetry/PhoneState.kt
Outdated
Show resolved
Hide resolved
...gation-core/src/main/java/com/mapbox/navigation/core/telemetry/TelemetryEventUserFeedback.kt
Outdated
Show resolved
Hide resolved
...igation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt
Outdated
Show resolved
Hide resolved
...igation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt
Outdated
Show resolved
Hide resolved
...igation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt
Outdated
Show resolved
Hide resolved
LukasPaczos
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good progress @olegzil. Adding to all other comments, I'd love to see an initial test structure implementation. The concepts you're introducing might allow us to collect metrics from any thread (another question is, do we need it?), but it'd be great if the architecture was designed in a testable manner from the get-go.
| .build() | ||
|
|
||
| // Call back that receives | ||
| private val routeProgressListener = object : RouteProgressObserver { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, and preferably it should already be parsed into whatever format the telemetry wrappers expect. This way, we're removing the cross dependency.
...igation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt
Outdated
Show resolved
Hide resolved
I am working on a set of Unit tests that should test this code extensively. Regarding the need for thread safety. Two answers regarding this subject. In this particular case the Telemetry class exposes one public method (not counting initialized()) and subscribes to two interfaces that have a combined three callbacks. On a more general note, the SDK has multiple Singletons, each maintains a state that can be accessed via the singletons public methods. We should consider making these singletons thread safe. Finally, do we want the SDK to be reactive? Making it reactive requires that no public method blocks the caller in addition to guaranteeing thread sefety. |
...igation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt
Outdated
Show resolved
Hide resolved
libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt
Outdated
Show resolved
Hide resolved
libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt
Outdated
Show resolved
Hide resolved
libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt
Outdated
Show resolved
Hide resolved
libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt
Outdated
Show resolved
Hide resolved
libnavigation-core/src/test/java/com/mapbox/navigation/core/MapboxNavigationTelemetryTest.kt
Outdated
Show resolved
Hide resolved
46d8acf to
f55d5b7
Compare
f55d5b7 to
ac7f487
Compare
libnavigation-core/src/test/java/com/mapbox/navigation/core/ContextCreationHelpers.kt
Outdated
Show resolved
Hide resolved
libnavigation-core/src/test/java/com/mapbox/navigation/core/MapboxNavigationTest.kt
Outdated
Show resolved
Hide resolved
libnavigation-core/src/test/java/com/mapbox/navigation/core/MapboxNavigationTest.kt
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| private fun validateAccessToken(accessToken: String?) { | ||
| if (accessToken.isNullOrEmpty() || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you might check it here
| if (accessToken.isNullOrEmpty() || | |
| if (accessToken.isNullOrEmpty() | |
| || ( !accessToken.toLowerCase(Locale.US).startsWith("pk.") | |
| || !accessToken.toLowerCase(Locale.US).startsWith("sk.")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be incorrect. a token can start with pk or sk. If we use an "or" than if either one is false, the entire if-statement fails. We want it to fail only if neither is correct. Neither is modeled with "and". Like this:
if (accessToken.isNullOrEmpty() || ( !accessToken.toLowerCase(Locale.US).startsWith("pk.") && !accessToken.toLowerCase(Locale.US).startsWith("sk."))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, you're right, thanks!
...gation-core/src/main/java/com/mapbox/navigation/core/telemetry/TelemetryEventUserFeedback.kt
Outdated
Show resolved
Hide resolved
2c918b3 to
dbea0ed
Compare
5597613 to
2908021
Compare
libnavigation-core/build.gradle
Outdated
| implementation dependenciesList.mapboxSdkTurf | ||
| implementation dependenciesList.mapboxAndroidAccounts | ||
| implementation dependenciesList.mapboxEvents | ||
| implementation project(':liblogger') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not depend on the liblogger module. We have to remove it anyway and wait for mapbox/mapbox-base-android#21 to be released. Please use android.util.Log until then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt
Outdated
Show resolved
Hide resolved
| /** | ||
| * Immutable and can't be changed after passing into [MapboxNavigation]. | ||
| */ | ||
| data class MapboxNavigationOptions( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove this class and use already present NavigationOptions if needed.
| * | ||
| * @since 0.1.0 | ||
| */ | ||
| object NavigationConstants { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove this class as well and move only the required constant into the correct file.
| .build() | ||
|
|
||
| // Call back that receives | ||
| private val routeProgressListener = object : RouteProgressObserver { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still valid.
| /** | ||
| * Register a callback to receive location events. At most [MAX_LOCATION_VALUES] are stored | ||
| */ | ||
| locationEngine.requestLocationUpdates(locationEngineRequest, locationCallback, null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was the legacy SDK's behavior? Were we collecting telemetry when navigation was not started? If we weren't we should listen from trip session updates instead.
settings.gradle
Outdated
| @@ -1,4 +1,4 @@ | |||
| include ':app', | |||
| include ':app', ':libnavigation-telemetry', | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no libnavigation-telemetry module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Guardiola31337
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@olegzil adding to the recent comments I left some other ones and questions.
Also, could you explain briefly how the approach we're taking is implemented? What's the overall APIs flow and architecture design? Could you provide examples / tests? I think that'd greatly help understanding the changes we're adding here and reviewing the PR will be easier.
libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt
Outdated
Show resolved
Hide resolved
| @@ -1,12 +1,8 @@ | |||
| package com.mapbox.navigation.metrics | |||
| package com.mapbox.navigation.core.metrics | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did we move the code from libnavigation-metrics to libnavigation-core? Wouldn't adding libnavigation-metrics dependency in libnavigation-core work? If something needs to be changed, we should update in libnavigation-metrics, that's fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The telemetry package classes are marked internal. For core to use them, they have to be in the included
| * Default implementation of [MetricsReporter] interface. | ||
| */ | ||
| object MapboxMetricsReporter : MetricsReporter { | ||
| class MapboxMetricsReporter( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation directs the anonymized data to Mapbox metric pipelines and exposes an observer that allows for inspecting and collecting any events that are going to be pushed into the Mapbox pipeline. In other words, it's just a wrapper around MapboxTelemetry and handles MetricsObserver logic and lifetime. Does it need to be a class? Why not an object anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 replaced
| /** | ||
| * Register a callback to receive location events. At most [MAX_LOCATION_VALUES] are stored | ||
| */ | ||
| locationEngine.requestLocationUpdates(locationEngineRequest, locationCallback, null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we're not currently collecting navigation specific telemetry until a session has started. When it comes to location updates though, telemetry is collected by Telemetry core / Maps if the end user grants her consent.
Related to location updates, an interesting question was raised: for these before and after location buffers, do we want to keep track of raw location updates or the fix locations coming from NN? Currently, in the legacy we're collecting and sending the location updates generated by the LocationEngine but we probably want to gather the fixed ones. What do you think? cc @coxchapman
| * Defines a contract in which a custom notification must adhere to when | ||
| * given to [com.mapbox.services.android.navigation.v5.navigation.MapboxNavigationOptions]. | ||
| */ | ||
| interface NavigationNotification { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this for Telemetry? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
| // Defaulted values are optional | ||
|
|
||
| @SuppressLint("ParcelCreator") | ||
| class TelemetryDepartureEvent( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above NavigationDepartEvent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NavigationEvent have been replaced by TelemetryEvent
| // Defaulted values are optional | ||
|
|
||
| @SuppressLint("ParcelCreator") | ||
| class TelemetryReroute( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above NavigationRerouteEvent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NavigationEvent have been replaced by TelemetryEvent
|
|
||
| // Defaulted values are optional | ||
|
|
||
| data class TelemetryStep( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above NavigationStepData
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TelemetryStep data is required for some of the feedback types. NavigationStepData no longer exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NavigationEvent have been replaced by TelemetryEvent
|
|
||
| // Defaulted values are optional | ||
| @SuppressLint("ParcelCreator") | ||
| class TelemetryUserFeedback( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above NavigationFeedbackEvent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outdated file. NavigationFeedbackEvent no longer exists. TelemetryFeedbackEvent is used instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All NavigationEvent have been replaced by TelemetryEvent
| @@ -0,0 +1,16 @@ | |||
| package com.mapbox.navigation.core.telemetry.audio | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Package directive doesn't match file location
Same thing applies to other classes 👇
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 removed
|
Also there are some conflicts (e.g. this https://github.com/mapbox/mapbox-navigation-android/pull/2445/files#diff-e3c60303e8ee1a7d01f2af9369235fa9R25 already changed in |
and user feedback events not being sent, if they where received in succession
16ca439 to
9584a6a
Compare
…e_called_with_bearings tests not working becasue of because of MapboxNavigationTelemetry#unregisterListeners initializer = initializerDelegate 777ebfa
83fa365 to
965f9c1
Compare
Description
Telemetry implementation. MapboxNavigationTelemetry is a singleton object that transmits all telemetry events to the back end servers. The usage of this class requires that it is thread thread safe. Although it has a single public method, postTelemetryEvent() that handles all possible telemetry data to be transmitted to the server, it also registers itself with MapboxNavigation to receive various updates. These updates are asynchronous and may arrive at the same time that postTelemetryEvent() call is active. The code makes sure that the notification and the call do not cause a race condition. This is done using two channels one receive location updates the other receives onProgress events. All calls that may read or write the internal buffers of MapboxNavigationTelemetry are serialized using LocationBufferControl. It contains the commend to execute and a lambda that represents the command. The method monitorChannels() is what serializes access.
Currently only User Feedback events are handled. Each event becomes a member variable of TelemetryUserFeedbackWrapper. One of these will have to be written for each event to be sent to the back end servers. So to generate the required event data, you have to implement a TelemetryWrapper that collects the required data for this event.
Please include a brief summary of the change and which issue is fixed (e.g., fixes #issue)
bug,feature,new API(s),SEMVER, etc.)Goal
Please describe the PR goals. Just the stuff needed to implement the fix / feature and a simple rationale. It could contain many check points if needed
Implementation
Please include all the relevant things implemented and also rationale, clarifications / disclaimers etc. related to the approach used. It could be as self code companion comments
Screenshots or Gifs
Please include all the media files to give some context about what's being implemented or fixed. It's not mandatory to upload screenshots or gifs, but for most of the cases it becomes really handy to get into the scope of the feature / bug being fixed and also it's REALLY useful for UI related PRs
Testing
Please describe the manual tests that you ran to verify your changes
SNAPSHOTupstream dependencies if needed) through testapp/demo app and run all activities to avoid regressionsChecklist
CHANGELOGincluding this PR