diff --git a/app/src/main/kotlin/com/mapzen/erasermap/controller/MainActivity.kt b/app/src/main/kotlin/com/mapzen/erasermap/controller/MainActivity.kt index aefb638c..2b7da24f 100644 --- a/app/src/main/kotlin/com/mapzen/erasermap/controller/MainActivity.kt +++ b/app/src/main/kotlin/com/mapzen/erasermap/controller/MainActivity.kt @@ -174,9 +174,10 @@ class MainActivity : AppCompatActivity(), MainViewController, override fun onNewIntent(intent: Intent?) { if (intent?.getBooleanExtra(NotificationCreator.EXIT_NAVIGATION, false) as Boolean) { - presenter.onExitNavigation() - if((intent?.getBooleanExtra(NotificationBroadcastReceiver.VISIBILITY, false) - as Boolean).not()) { + val visible = intent?.getBooleanExtra(NotificationBroadcastReceiver.VISIBILITY, false) + presenter.willPauseImmediately = !visible + presenter.onExitNavigation(visible) + if (!visible) { moveTaskToBack(true) } } else { @@ -229,6 +230,7 @@ class MainActivity : AppCompatActivity(), MainViewController, override public fun onPause() { super.onPause() + presenter.willPauseImmediately = false app.onActivityPause() if (mapzenMap?.isMyLocationEnabled != null && mapzenMap?.isMyLocationEnabled as Boolean && !presenter.routingEnabled) { diff --git a/app/src/main/kotlin/com/mapzen/erasermap/presenter/MainPresenter.kt b/app/src/main/kotlin/com/mapzen/erasermap/presenter/MainPresenter.kt index 9f60ae14..d186773e 100644 --- a/app/src/main/kotlin/com/mapzen/erasermap/presenter/MainPresenter.kt +++ b/app/src/main/kotlin/com/mapzen/erasermap/presenter/MainPresenter.kt @@ -32,6 +32,7 @@ interface MainPresenter { var poiTapPoint: FloatArray? var poiTapName: String? var poiCoordinates: LngLat? + var willPauseImmediately: Boolean? fun onSearchResultsAvailable(result: Result?) fun onReverseGeocodeResultsAvailable(searchResults: Result?) @@ -57,7 +58,7 @@ interface MainPresenter { fun onMapRotateEvent(): Boolean fun onReverseGeoRequested(screenX: Float?, screenY: Float?): Boolean fun onPlaceSearchRequested(gid: String): Boolean - fun onExitNavigation() + fun onExitNavigation(visible: Boolean) fun configureMapzenMap() fun onIntentQueryReceived(query: String?) fun onRouteRequest(callback: RouteCallback) diff --git a/app/src/main/kotlin/com/mapzen/erasermap/presenter/MainPresenterImpl.kt b/app/src/main/kotlin/com/mapzen/erasermap/presenter/MainPresenterImpl.kt index 471d080a..f5646cd2 100644 --- a/app/src/main/kotlin/com/mapzen/erasermap/presenter/MainPresenterImpl.kt +++ b/app/src/main/kotlin/com/mapzen/erasermap/presenter/MainPresenterImpl.kt @@ -76,6 +76,7 @@ open class MainPresenterImpl(val mapzenLocation: MapzenLocation, val bus: Bus, override var poiTapPoint: FloatArray? = null override var poiTapName: String? = null override var poiCoordinates: LngLat? = null + override var willPauseImmediately: Boolean? = false private var searchResults: Result? = null private var destination: Feature? = null @@ -590,7 +591,7 @@ open class MainPresenterImpl(val mapzenLocation: MapzenLocation, val bus: Bus, } override fun onResume() { - if (!isRouting() && !isRoutingDirectionList()) { + if (!isRouting() && !isRoutingDirectionList() && !willPauseImmediately()) { mainViewController?.checkPermissionAndEnableLocation() } } @@ -599,6 +600,11 @@ open class MainPresenterImpl(val mapzenLocation: MapzenLocation, val bus: Bus, return vsm.viewState == ViewStateManager.ViewState.ROUTING } + private fun willPauseImmediately(): Boolean { + val willPause = willPauseImmediately?.let { it } ?: return false + return willPause + } + private fun isRoutingDirectionList(): Boolean { return vsm.viewState == ViewStateManager.ViewState.ROUTE_DIRECTION_LIST } @@ -682,11 +688,18 @@ open class MainPresenterImpl(val mapzenLocation: MapzenLocation, val bus: Bus, } } - override fun onExitNavigation() { + override fun onExitNavigation(visible: Boolean) { vsm.viewState = ViewStateManager.ViewState.DEFAULT routingEnabled = false routeManager.reverse = false - checkPermissionAndEnableLocation() + + val currentLocation = mapzenLocation.getLastLocation() + mapzenLocation.stopLocationUpdates() + mainViewController?.stopSpeaker() + + if (visible) { + checkPermissionAndEnableLocation() + } mainViewController?.stopVoiceNavigationController() mainViewController?.clearRoute() mainViewController?.hideRouteIcon() @@ -697,6 +710,11 @@ open class MainPresenterImpl(val mapzenLocation: MapzenLocation, val bus: Bus, mainViewController?.setDefaultCamera() mainViewController?.layoutFindMeAlignBottom() mainViewController?.setMapTilt(0f) + + if (currentLocation is Location) { + mainViewController?.centerMapOnLocation(LngLat(currentLocation.longitude, + currentLocation.latitude), MainPresenter.DEFAULT_ZOOM) + } } override fun onMapRotateEvent(): Boolean { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index f9d74da7..1d09e3fe 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,6 @@ ? = null var searchResultsPoints: List? = null var searchResultsCleared = false - + var speakerStopped = false var screenPosLngLat: LngLat? = null override fun showSearchResultsView(features: List) { @@ -241,7 +241,7 @@ class TestMainController : MainViewController { } override fun stopSpeaker() { - + speakerStopped = true } override fun checkPermissionAndEnableLocation() { diff --git a/app/src/test/kotlin/com/mapzen/erasermap/model/TestMapzenLocation.kt b/app/src/test/kotlin/com/mapzen/erasermap/model/TestMapzenLocation.kt index e1663710..0b770917 100644 --- a/app/src/test/kotlin/com/mapzen/erasermap/model/TestMapzenLocation.kt +++ b/app/src/test/kotlin/com/mapzen/erasermap/model/TestMapzenLocation.kt @@ -13,6 +13,8 @@ class TestMapzenLocation : MapzenLocation { override var mapzenMap: MapzenMap? = null + var testLastLocation = Mockito.mock(Location::class.java) + override fun startLocationUpdates() { connected = true } @@ -22,7 +24,7 @@ class TestMapzenLocation : MapzenLocation { } override fun getLastLocation(): Location? { - return Mockito.mock(Location::class.java) + return testLastLocation } override fun getLon(): Double { diff --git a/app/src/test/kotlin/com/mapzen/erasermap/presenter/MainPresenterTest.kt b/app/src/test/kotlin/com/mapzen/erasermap/presenter/MainPresenterTest.kt index fef4d6a4..dd565426 100644 --- a/app/src/test/kotlin/com/mapzen/erasermap/presenter/MainPresenterTest.kt +++ b/app/src/test/kotlin/com/mapzen/erasermap/presenter/MainPresenterTest.kt @@ -26,6 +26,7 @@ import com.mapzen.erasermap.model.ValhallaRouteManagerTest.TestRouteCallback import com.mapzen.erasermap.model.event.LocationChangeEvent import com.mapzen.erasermap.model.event.RouteCancelEvent import com.mapzen.erasermap.model.event.RoutePreviewEvent +import com.mapzen.erasermap.presenter.MainPresenter.Companion.DEFAULT_ZOOM import com.mapzen.erasermap.presenter.ViewStateManager.ViewState.DEFAULT import com.mapzen.erasermap.presenter.ViewStateManager.ViewState.ROUTE_DIRECTION_LIST import com.mapzen.erasermap.presenter.ViewStateManager.ViewState.ROUTE_PREVIEW @@ -936,6 +937,14 @@ class MainPresenterTest { assertThat(mapzenLocation.connected).isFalse() } + @Test fun onResume_shouldNotClientWhenExitRoutingNotificationInvokedWhileNotVisible() { + presenter.willPauseImmediately = true + presenter.onClickStartNavigation() + mapzenLocation.connected = false + presenter.onResume() + assertThat(mapzenLocation.connected).isFalse() + } + @Test fun onBackPressed_shouldUpdateViewState() { vsm.viewState = ROUTE_DIRECTION_LIST presenter.onBackPressed() @@ -1302,89 +1311,119 @@ class MainPresenterTest { @Test fun onExitNavigation_shouldSetViewStateDefault() { vsm.viewState = ROUTING - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(vsm.viewState).isEqualTo(DEFAULT) } @Test fun onExitNavigation_shouldDisableRouting() { presenter.routingEnabled = true - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(presenter.routingEnabled).isFalse() } @Test fun onExitNavigation_shouldResetReverse() { routeManager.reverse = true - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(routeManager.reverse).isFalse() } @Test fun onExitNavigation_shouldEnableLocation() { permissionManager.granted = true mainController.isCurrentLocationEnabled = false - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(mainController.isCurrentLocationEnabled).isTrue() } + @Test fun onExitNavigation_shouldNotEnableLocation() { + permissionManager.granted = true + mainController.isCurrentLocationEnabled = false + presenter.onExitNavigation(false) + assertThat(mainController.isCurrentLocationEnabled).isFalse() + } + @Test fun onExitNavigation_shouldStopVoiceNavigationController() { mainController.isVoiceNavigationStopped = false - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(mainController.isVoiceNavigationStopped).isTrue() } @Test fun onExitNavigation_shouldClearRoute() { mainController.routeLine = Route(JSONObject()) - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(mainController.routeLine).isNull() } @Test fun onExitNavigation_shouldHideRouteIcon() { mainController.isRouteIconVisible = true - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(mainController.isRouteIconVisible).isFalse() } @Test fun onExitNavigation_shouldHideRouteModeView() { mainController.isRouteModeViewVisible = true - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(mainController.isRouteModeViewVisible).isFalse() } @Test fun onExitNavigation_shouldShowActionBar() { mainController.isActionBarHidden = true - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(mainController.isActionBarHidden).isFalse() } @Test fun onExitNavigation_shouldHideRoutePreviewView() { mainController.isRoutePreviewViewVisible = true - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(mainController.isRoutePreviewViewVisible).isFalse() } @Test fun onExitNavigation_shouldResetMapResponder() { mainController.mapHasPanResponder = true - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(mainController.mapHasPanResponder).isFalse() } @Test fun onExitNavigation_shouldSetDefaultCamera() { mainController.mapCameraType = MapController.CameraType.PERSPECTIVE - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(mainController.mapCameraType).isEqualTo(MapController.CameraType.ISOMETRIC) } @Test fun onExitNavigation_shouldAlignFindMeToBottom() { mainController.isFindMeAboveOptions = true - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(mainController.isFindMeAboveOptions).isFalse() } @Test fun onExitNavigation_shouldResetMapTilt() { mainController.tilt = 30f - presenter.onExitNavigation() + presenter.onExitNavigation(true) assertThat(mainController.tilt).isEqualTo(0f) } + @Test fun onExitNavigation_shouldStopLocationUpdates() { + mapzenLocation.startLocationUpdates() + presenter.onExitNavigation(true) + assertThat(mapzenLocation.connected).isFalse() + } + + @Test fun onExitNavigation_shouldStopSpeaker() { + mainController?.speakerStopped = false + presenter.onExitNavigation(true) + assertThat(mainController?.speakerStopped).isTrue() + } + + @Test fun onExitNavigation_shouldCenterOnLastLocation() { + mainController?.lngLat = null + mainController?.zoom = -1f + `when`(mapzenLocation?.testLastLocation.latitude).thenReturn(40.0) + `when`(mapzenLocation?.testLastLocation.longitude).thenReturn(70.0) + presenter.onExitNavigation(true) + assertThat(mainController?.lngLat?.latitude).isEqualTo(40.0) + assertThat(mainController?.lngLat?.longitude).isEqualTo(70.0) + assertThat(mainController?.zoom).isEqualTo(DEFAULT_ZOOM) + } + @Test fun centerOnCurrentFeature_shouldDoNothingForNoFeatures() { val result = Result() presenter.onSearchResultsAvailable(result)