Skip to content
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

Remove use of LiveData for fetching DirectionsRoute and updating Location #894

Merged
merged 3 commits into from
May 1, 2018

Conversation

danesfeder
Copy link
Contributor

@danesfeder danesfeder commented Apr 27, 2018

Closes #750 Closes #877

We currently use LiveData to update new DirectionsRoutes (such as an off-route event) and Location updates (previously RouteViewModel and LocationViewModel).

This PR removes these vm's and replaces them with classes that has callbacks and can operate in the background without issue.

TODO:

  • Unit tests
  • Fix leak in NavigationCamera

@danesfeder danesfeder added bug Defect to be fixed. navigation-ui labels Apr 27, 2018
@danesfeder danesfeder added this to the v0.13.0 milestone Apr 27, 2018
@danesfeder danesfeder self-assigned this Apr 27, 2018
@danesfeder
Copy link
Contributor Author

@devotaaabel @Guardiola31337 created a new pull request after my git fail

@danesfeder danesfeder force-pushed the dan-vm-arch branch 2 times, most recently from fad1b4c to 14d6ff2 Compare April 30, 2018 17:42
Copy link
Contributor

@Guardiola31337 Guardiola31337 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice cleanup and test coverage 👏

Some comments/questions before getting in.

@Override
public void onStart() {
super.onStart();
navigationView.onStart();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if we could use Lifecycle Architecture Component https://developer.android.com/topic/libraries/architecture/lifecycle here to remove ☝️ boilerplate code from all activities containing a NavigationView. Saw that @OnLifecycleEvents were removed as part of this PR, wondering why 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed this with @Guardiola31337 - making it manual for now is fine, noting that we should look into how to properly handle the Fragment architecture with the annotations.

*
* @param onNavigationReadyCallback to be set to this view
*/
public void getNavigationAsync(OnNavigationReadyCallback onNavigationReadyCallback) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we revisit the method's name? We're not getting anything actually (note void). BTW, this method is doing 2 things, setting onNavigationReadyCallback and a callback object that will be triggered when the map is ready to be used. Shouldn't the latter managed somewhere else?

* @param navigationViewOptions that contains all listeners to attach
*/
void initializeListeners(NavigationViewOptions navigationViewOptions, MapboxNavigation navigation) {
setFeedbackListener(navigationViewOptions.feedbackListener());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get/set nomenclature is hijacked by the Java language and should be only used when defining POJOs/DTOs. Especially here that the methods are package-private.

/**
* Adds this class as a listener for progress,
* milestones, and off route events.
*/
private void addNavigationListeners() {
if (navigation != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How could navigation be null? I guess that's not possible because we're calling addNavigationListeners from initNavigation which initializes it. Am I missing something? If not, this check could be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, good 👁 here @Guardiola31337


private void initLocationEngine(Context context, boolean simulateRoute) {
if (simulateRoute) {
locationEngine = new MockLocationEngine(1000, 30, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic numbers.

NavigationLocationEngineListener mockCallback = mock(NavigationLocationEngineListener.class);
NavigationLocationEngine navigationLocationEngine = new NavigationLocationEngine(mockCallback);

navigationLocationEngine.initializeLocationEngine(createMockContext(), true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this is part of the Arrange part.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be explicit with the true that we're passing in because that's key for what we're testing here. What about extracting it to a explaining variable and name it simulationEnabled for example?

}

@Test
public void onSecondResponseReceived_routesAreCompared() throws Exception {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be explicit on onSecondResponseReceived somehow to know what's going on here in a glance. Are we enabling some option in buildNavigationEngineWithOptions? Wondering how this test differs from onResponseReceived_routeIsProcessed one 🤔

* @since 0.13.0
*/
@Override
public void findRouteFromRouteProgress(Location location, RouteProgress routeProgress) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could refactor findRouteFromRouteProgress (decompose conditionals, extract blocks of code into well-named methods, etc.). We should keep public methods as clean as possible so they read like pseudocode (i.e. no conditionals, fors, etc.).

}

@Nullable
private static NavigationRoute.Builder buildRouteRequestFromCurrentLocation(Point origin, Double bearing,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why buildRouteRequestFromCurrentLocation needs to be static? Same for addRouteProfile, addDestination, retrieveDestinationWaypoint and addWaypoints methods.

import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.services.android.navigation.v5.location.MockLocationEngine;

public class NavigationLocationEngine {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this name a little consfusing? Maybe it could be NavigationLocationEngineManager or something

import java.util.List;
import java.util.Locale;

public class NavigationViewRouteEngine extends NavigationRouteEngine implements RouteEngineListener {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again is Engine the right word here? Maybe Manager? And I'm not sure I understand this whole hierarchy (NavigationViewRouteEngine -> NavigationRouteEngine -> RouteEngine)

* @param navigationViewOptions that contains all listeners to attach
*/
void initializeListeners(NavigationViewOptions navigationViewOptions, MapboxNavigation navigation) {
updateFeedbackListener(navigationViewOptions.feedbackListener());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we updating the listeners? What about using assign instead?

BTW, for consistency we should use Listener or Callback across the base code. Saw that sometimes we name callbacks as Listener and sometimes as Callback. This is something that we could revisit later.

}

@Test
public void onSecondRouteResponseReceived_routesAreComparedWithDamerauLevenshteinAlgorithm() throws Exception {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 #894 (comment)

We should be explicit on onSecondResponseReceived somehow to know what's going on here in a glance. Are we enabling some option in buildNavigationEngineWithOptions? Wondering how this test differs from onResponseReceived_routeIsProcessed one 🤔

return remainingWaypoints.remove(lastWaypoint);
}

private static void addWaypoints(List<Point> remainingCoordinates, NavigationRoute.Builder builder) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 #894 (comment)

It seems you missed this one. Any reasons?

Copy link
Contributor

@Guardiola31337 Guardiola31337 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's 🚢

Well done @danesfeder 🙇

@@ -36,7 +36,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
super.onViewCreated(view, savedInstanceState);
navigationView = view.findViewById(R.id.navigation_view_fragment);
navigationView.onCreate(savedInstanceState);
navigationView.getNavigationAsync(this);
navigationView.initialize(this);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@danesfeder danesfeder merged commit e746a46 into master May 1, 2018
@danesfeder danesfeder deleted the dan-vm-arch branch June 12, 2018 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Defect to be fixed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants