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

Route tile download #1559

Merged
merged 29 commits into from
Nov 30, 2018
Merged

Route tile download #1559

merged 29 commits into from
Nov 30, 2018

Conversation

devotaaabel
Copy link
Contributor

I am still implementing changes we talked about including the update to navigator 3.4.3, adding better error reporting, and changing the public API to not include RoutingTileDownloadManager and instead add a startDownload method in MapboxOfflineRouter. Also going to add some simple unit tests.

@devotaaabel devotaaabel added the feature New feature request. label Nov 27, 2018
@devotaaabel devotaaabel added this to the v0.24.0 milestone Nov 27, 2018
@devotaaabel devotaaabel self-assigned this Nov 27, 2018
@codecov-io
Copy link

codecov-io commented Nov 28, 2018

Codecov Report

Merging #1559 into master will decrease coverage by 0.19%.
The diff coverage is 3.84%.

@@             Coverage Diff             @@
##             master    #1559     +/-   ##
===========================================
- Coverage     22.75%   22.56%   -0.2%     
- Complexity      689      694      +5     
===========================================
  Files           182      189      +7     
  Lines          8102     8230    +128     
  Branches        599      606      +7     
===========================================
+ Hits           1844     1857     +13     
- Misses         6075     6190    +115     
  Partials        183      183

@Guardiola31337
Copy link
Contributor

Guardiola31337 commented Nov 28, 2018

During local testing, I run into the following 💥

offline_crash

    --------- beginning of crash
11-28 09:40:34.869 17608-17608/com.mapbox.services.android.navigation.testapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.mapbox.services.android.navigation.testapp, PID: 17608
    java.lang.RuntimeException: Unable to destroy activity {com.mapbox.services.android.navigation.testapp/com.mapbox.services.android.navigation.testapp.example.ui.ExampleActivity}: java.lang.ClassCastException: com.mapbox.services.android.navigation.v5.navigation.camera.SimpleCamera cannot be cast to com.mapbox.services.android.navigation.ui.v5.camera.DynamicCamera
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3831)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3849)
        at android.app.ActivityThread.-wrap5(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.ClassCastException: com.mapbox.services.android.navigation.v5.navigation.camera.SimpleCamera cannot be cast to com.mapbox.services.android.navigation.ui.v5.camera.DynamicCamera
        at com.mapbox.services.android.navigation.testapp.example.ui.ExampleViewModel.shutdown(ExampleViewModel.kt:164)
        at com.mapbox.services.android.navigation.testapp.example.ui.ExampleViewModel.onCleared(ExampleViewModel.kt:97)
        at android.arch.lifecycle.ViewModelStore.clear(ViewModelStore.java:56)
        at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:387)
        at android.support.v7.app.AppCompatActivity.onDestroy(AppCompatActivity.java:209)
        at com.mapbox.services.android.navigation.testapp.example.ui.ExampleActivity.onDestroy(ExampleActivity.kt:86)
        at android.app.Activity.performDestroy(Activity.java:6407)
        at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1142)
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3818)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3849) 
        at android.app.ActivityThread.-wrap5(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5417) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Nexus 5 - Android 6.0

Also I want to note that we're not requesting the location updates after granting the permissions - there's no location icon in the status bar as shown above.

@devotaaabel
Copy link
Contributor Author

@Guardiola31337 can you put that in a separate ticket? That looks unrelated to anything in this PR.

@Guardiola31337
Copy link
Contributor

@devotaaabel

can you put that in a separate ticket? That looks unrelated to anything in this PR.

I brought this up because it's working in master. My guess is that we're messing up with the storage permissions added as part of this PR.

Copy link
Contributor

@danesfeder danesfeder left a comment

Choose a reason for hiding this comment

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

@devotaaabel this is looking great! 👍 I left some comments for updates / questions that we can discuss.

One thing I noticed regarding the test app, it seems the app isn't currently aware of changes from settings when resuming. So going from online to offline results in no route found:

ezgif com-video-to-gif 16-18-25-139

I think this is due to the offline router being created as null during initialization:

screen shot 2018-11-28 at 3 37 07 pm

@@ -452,6 +454,11 @@ private void generateFeatureCollectionList(List<DirectionsRoute> directionsRoute
// Each route contains traffic information and should be recreated considering this traffic
// information.
for (int i = 0; i < directionsRoutes.size(); i++) {

Timber.d("DirectionsRoutes.size " + directionsRoutes.size());
Timber.d("direction route " + directionsRoutes.get(i));
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we remove these logs?

libandroid-navigation/src/main/AndroidManifest.xml Outdated Show resolved Hide resolved
CONFIGURE_ROUTER_RESULT_SUCCESS(true), CONFIGURE_ROUTER_RESULT_FAILURE(false);

private final boolean success;
Status(boolean success) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the success boolean needed here? It seems you may be able to infer success or failure based on the Status value itself.

*/
void routesFound(List<DirectionsRoute> routes);

void onError(OfflineData offlineData);
Copy link
Contributor

Choose a reason for hiding this comment

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

We renamed this to RouteFoundCallback but it looks like the the error callback here is specific to offline with OfflineData. Are we using this callback anywhere that isn't for an offline purpose? (necessitating the change to a more generic name).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's being used here https://github.com/mapbox/mapbox-navigation-android/blob/devota-route-tile-download/app/src/main/java/com/mapbox/services/android/navigation/testapp/example/ui/navigation/ExampleRouteFinder.kt#L46 I think for consistency and being able to implement one callback for both online and offline routes it is nice to have one for both, maybe we could also put RouteFoundCallback here? https://github.com/mapbox/mapbox-navigation-android/blob/devota-route-tile-download/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRoute.java#L79 But about the OfflineData, I'd like to talk about that, so we can hopefully come to a consensus about the best way to track errors, that was just my first attempt at an error reporting object.

NavigationLibraryLoader.load();
}

TileUnpacker() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it make sense to pass the Navigator created in the MapboxOfflineRouter to the RouteTileDownloader and then ultimately here in the TileUnpacker?

*/
void unpack(File src, String destPath, UnpackUpdateTask.ProgressUpdateListener updateListener) {
Log.d("source path", "" + src.getAbsolutePath());
Log.d("dest path", "" + destPath);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we remove these logs?

long size = tar.length();

while (tar.length() > 0) {
publishProgress((((tar.length() / size)) * 100));
Copy link
Contributor

Choose a reason for hiding this comment

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

I noticed that the published progress here is either 0 or 100 - was this expected behavior?

screen shot 2018-11-28 at 3 50 56 pm

@Guardiola31337 said he had some ideas about a buffer to monitor this? @kevinkreiser any ideas what the issue is with monitoring the tar unpacking? Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

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

im going to take a stab at fixing this!

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.

@devotaaabel this is looking good - some questions and comments to discuss 👍

* can be called safely.
*/
public void initializeOfflineData(String tilesDirPath, OnOfflineDataInitialized callback) {
offlineNavigator.configure(tilesDirPath, callback);
public void initializeOfflineData(String version, OnOfflineDataInitialized callback) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor comment / question
Have we considered using initializeData instead of initializeOfflineData? We're in the context of MapboxOfflineRouter so adding Offline sounds redundant to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Guardiola31337 I actually think configureRouter would make the most sense here, because you are configuring it be ready to use the version you specified. Do we know why we went with initializeData?

Copy link
Contributor

Choose a reason for hiding this comment

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

@devotaaabel yeah! In that case I'd name it configure (initialize also could work) because we're in the context of MapboxOfflineRouter, no need to add Router again IMO.

@@ -33,8 +48,17 @@ public void initializeOfflineData(String tilesDirPath, OnOfflineDataInitialized
* @return the offline {@link DirectionsRoute}
*/
@Nullable
public void findOfflineRoute(@NonNull OfflineRoute route,
OfflineRouteFoundCallback callback) {
public void findOfflineRoute(@NonNull OfflineRoute route, RouteFoundCallback callback) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here re: Offline redundancy

private final Navigator navigator;

static {
NavigationLibraryLoader.load();
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe this is re-loading NN unnecessarily because it's already done when instantiating OfflineNavigator which happens when creating a MapboxOfflineRouter. I guess it's safe to remove it here.


@Override
protected File doInBackground(String... strings) {
navigator.unpackTiles(strings[0], strings[1]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't navigator.unpackTiles be synchronized?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Guardiola31337 nope I asked, @kevinkreiser said it can be considered a static method

outputStream.flush();
return file;

} catch (IOException 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're currently catching IOException twice 👇 I believe that's not necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Guardiola31337 the finally block throws an IOException

public class DownloadTask extends AsyncTask<ResponseBody, Void, File> {

private static final int END_OF_FILE_DENOTER = -1;
private static int instructionNamingInt = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Have we considered making instructionNamingInt non static?

@danesfeder
Copy link
Contributor

Amazing work here @devotaaabel, this was no small effort. Huge milestone for the SDK 🚀

@Guardiola31337
Copy link
Contributor

Amazing work here @devotaaabel, this was no small effort. Huge milestone for the SDK 🚀

I second that. Kudos @devotaaabel

@devotaaabel devotaaabel merged commit b46b7b7 into master Nov 30, 2018
@devotaaabel devotaaabel deleted the devota-route-tile-download branch November 30, 2018 01:51
@Guardiola31337 Guardiola31337 mentioned this pull request Nov 30, 2018
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature request.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants