From 2ffdc353f3eb9b15044d2627c75c8a0a2afa8503 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Wed, 25 Jul 2018 16:11:59 +0300 Subject: [PATCH] Fixed transfer to not follow mode, improved lose location logic --- .../maps/location/AndroidNativeProvider.java | 21 +--- .../maps/location/LocationHelper.java | 10 +- .../com/mapswithme/util/LocationUtils.java | 2 - drape_frontend/frontend_renderer.cpp | 2 +- drape_frontend/my_position_controller.cpp | 108 ++++++++++++++---- drape_frontend/my_position_controller.hpp | 7 +- 6 files changed, 92 insertions(+), 58 deletions(-) diff --git a/android/src/com/mapswithme/maps/location/AndroidNativeProvider.java b/android/src/com/mapswithme/maps/location/AndroidNativeProvider.java index 07ad08f83f..54017d6893 100644 --- a/android/src/com/mapswithme/maps/location/AndroidNativeProvider.java +++ b/android/src/com/mapswithme/maps/location/AndroidNativeProvider.java @@ -8,7 +8,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.mapswithme.maps.MwmApplication; -import com.mapswithme.util.LocationUtils; import java.util.ArrayList; import java.util.List; @@ -60,17 +59,9 @@ class AndroidNativeProvider extends BaseLocationProvider LocationHelper.INSTANCE.startSensors(); - Location location = findBestNotExpiredLocation(mLocationManager, providers, - LocationUtils.LOCATION_EXPIRATION_TIME_MILLIS_SHORT); + Location location = findBestLocation(mLocationManager, providers); if (location != null && !getLocationFixChecker().isLocationBetterThanLast(location)) - { location = LocationHelper.INSTANCE.getSavedLocation(); - if (location == null || LocationUtils.isExpired(location, LocationHelper.INSTANCE.getSavedLocationTime(), - LocationUtils.LOCATION_EXPIRATION_TIME_MILLIS_SHORT)) - { - return; - } - } if (location != null) onLocationChanged(location); @@ -101,16 +92,14 @@ class AndroidNativeProvider extends BaseLocationProvider } @Nullable - static Location findBestNotExpiredLocation(long expirationMillis) + static Location findBestLocation() { final LocationManager manager = (LocationManager) MwmApplication.get().getSystemService(Context.LOCATION_SERVICE); - return findBestNotExpiredLocation(manager, - getAvailableProviders(manager), - expirationMillis); + return findBestLocation(manager, getAvailableProviders(manager)); } @Nullable - private static Location findBestNotExpiredLocation(LocationManager manager, List providers, long expirationMillis) + private static Location findBestLocation(LocationManager manager, List providers) { Location res = null; try @@ -118,7 +107,7 @@ class AndroidNativeProvider extends BaseLocationProvider for (final String pr : providers) { final Location last = manager.getLastKnownLocation(pr); - if (last == null || LocationUtils.isExpired(last, last.getTime(), expirationMillis)) + if (last == null) continue; if (res == null || res.getAccuracy() > last.getAccuracy()) diff --git a/android/src/com/mapswithme/maps/location/LocationHelper.java b/android/src/com/mapswithme/maps/location/LocationHelper.java index 9d1b53b3e8..37fe7962c1 100644 --- a/android/src/com/mapswithme/maps/location/LocationHelper.java +++ b/android/src/com/mapswithme/maps/location/LocationHelper.java @@ -643,18 +643,12 @@ public enum LocationHelper * @return {@code null} on failure. */ @Nullable - public Location getLastKnownLocation(long expirationMillis) + public Location getLastKnownLocation() { if (mSavedLocation != null) return mSavedLocation; - return AndroidNativeProvider.findBestNotExpiredLocation(expirationMillis); - } - - @Nullable - public Location getLastKnownLocation() - { - return getLastKnownLocation(LocationUtils.LOCATION_EXPIRATION_TIME_MILLIS_LONG); + return AndroidNativeProvider.findBestLocation(); } @Nullable diff --git a/android/src/com/mapswithme/util/LocationUtils.java b/android/src/com/mapswithme/util/LocationUtils.java index 07fe2a521c..aa6916338c 100644 --- a/android/src/com/mapswithme/util/LocationUtils.java +++ b/android/src/com/mapswithme/util/LocationUtils.java @@ -22,8 +22,6 @@ public class LocationUtils { private LocationUtils() {} - public static final long LOCATION_EXPIRATION_TIME_MILLIS_SHORT = 60 * 1000; // 1 minute - public static final long LOCATION_EXPIRATION_TIME_MILLIS_LONG = 6 * 60 * 60 * 1000; // 6 hours private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.LOCATION); private static final String TAG = LocationUtils.class.getSimpleName(); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 45f180dae5..beaa64ddff 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -2236,7 +2236,7 @@ void FrontendRenderer::CheckAndRunFirstLaunchAnimation() } int constexpr kDesiredZoomLevel = 13; - m2::PointD const pos = m_myPositionController->GetDrawablePosition(); + m2::PointD const pos = m_myPositionController->GetDrawablePosition(); AddUserEvent(make_unique_dp(pos, kDesiredZoomLevel, true /* isAnim */, false /* trackVisibleViewport */)); } diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index 63d37c7e0a..62999aca34 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -148,7 +148,6 @@ MyPositionController::MyPositionController(Params && params, ref_ptr(system_clock::now().time_since_epoch()).count() - info.m_timestamp; + if (delta >= kMaxUpdateLocationInvervalSec) { - ChangeMode(location::NotFollow); - ResetRoutingNotFollowTimer(); - m_notFollowAfterPending = false; + m_positionIsObsolete = true; + m_autoScale2d = m_autoScale3d = kUnknownAutoZoom; } - else if (!m_isPositionAssigned) + else { - ChangeMode(m_hints.m_isFirstLaunch ? location::Follow : m_desiredInitMode); + m_positionIsObsolete = false; + } + + // If we are on the start, the first known location is obsolete, the new one has come and + // we didn't touch the map. In this case we allow to go from NotFollow to Follow. + bool canChangeNotFollowMode = false; + if (m_allowToFollowAfterObsoletePosition && !m_notFollowAfterPending && + previousPositionIsObsolete && !m_positionIsObsolete) + { + canChangeNotFollowMode = true; + m_allowToFollowAfterObsoletePosition = false; + } + + if (!m_isPositionAssigned) + { + // If the position was never assigned, the new mode will be desired one except the case when + // we touch the map during the pending of position. In this case the new mode will be NotFollow to + // prevent spontaneous map snapping. + location::EMyPositionMode newMode = m_desiredInitMode; + if (m_notFollowAfterPending && m_mode == location::PendingPosition) + { + ResetRoutingNotFollowTimer(); + m_notFollowAfterPending = false; + newMode = location::NotFollow; + } + ChangeMode(newMode); + if (!m_hints.m_isFirstLaunch || !AnimationSystem::Instance().AnimationExists(Animation::Object::MapPlane)) { if (m_mode == location::Follow) @@ -442,7 +483,8 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool } } } - else if (m_mode == location::PendingPosition || m_mode == location::NotFollowNoPosition) + else if (m_mode == location::PendingPosition || + (m_mode == location::NotFollow && canChangeNotFollowMode)) { if (m_isInRouting) { @@ -451,8 +493,18 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool } else { - ChangeMode(location::Follow); - if (!m_hints.m_isFirstLaunch) + // Here we prevent to go to Follow mode in the case when we touch the map + // during the pending of position. + location::EMyPositionMode newMode = location::Follow; + if (m_notFollowAfterPending && m_mode == location::PendingPosition) + { + ResetRoutingNotFollowTimer(); + m_notFollowAfterPending = false; + newMode = location::NotFollow; + } + ChangeMode(newMode); + + if (!m_hints.m_isFirstLaunch && m_mode == location::Follow) { if (GetZoomLevel(screen, m_position, m_errorRadius) <= kMaxScaleZoomLevel) { @@ -471,10 +523,13 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool } } } + else if (m_mode == location::NotFollowNoPosition) + { + // Here we silently get the position and go to NotFollow mode. + ChangeMode(location::NotFollow); + } m_isPositionAssigned = true; - m_positionIsObsolete = false; - SetIsVisible(true); if (m_listener != nullptr) m_listener->PositionChanged(Position(), IsModeHasPosition()); @@ -490,13 +545,22 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool void MyPositionController::LoseLocation() { - if (m_mode != location::NotFollowNoPosition) + if (!IsModeHasPosition()) + return; + + if (m_mode == location::Follow || m_mode == location::FollowAndRotate) + { + m_pendingTimer.Reset(); + m_locationWaitingNotifyId = DrapeNotifier::kInvalidId; + ChangeMode(location::PendingPosition); + } + else { ChangeMode(location::NotFollowNoPosition); - SetIsVisible(false); - if (m_listener != nullptr) - m_listener->PositionChanged(Position(), false /* hasPosition */); } + + if (m_listener != nullptr) + m_listener->PositionChanged(Position(), false /* hasPosition */); } void MyPositionController::OnCompassUpdate(location::CompassInfo const & info, ScreenBase const & screen) @@ -517,12 +581,6 @@ void MyPositionController::OnCompassUpdate(location::CompassInfo const & info, S } } -bool MyPositionController::IsInStateWithPosition() const -{ - return m_mode == location::NotFollow || m_mode == location::Follow || - m_mode == location::FollowAndRotate; -} - bool MyPositionController::UpdateViewportWithAutoZoom() { double autoScale = m_enablePerspectiveInRouting ? m_autoScale3d : m_autoScale2d; @@ -542,7 +600,7 @@ void MyPositionController::Render(ScreenBase const & screen, int zoomLevel, CheckIsWaitingForLocation(); CheckNotFollowRouting(); - if (m_shape != nullptr && IsVisible() && IsModeHasPosition()) + if (m_shape != nullptr && IsModeHasPosition()) { CheckBlockAutoZoom(); CheckUpdateLocation(); diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index b95e83fceb..63cd790ee3 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -133,11 +133,6 @@ public: private: void ChangeMode(location::EMyPositionMode newMode); void SetDirection(double bearing); - - bool IsInStateWithPosition() const; - - bool IsVisible() const { return m_isVisible; } - void SetIsVisible(bool isVisible) { m_isVisible = isVisible; } void ChangeModelView(m2::PointD const & center, int zoomLevel); void ChangeModelView(double azimuth); @@ -201,7 +196,6 @@ private: m2::RectD m_visiblePixelRect; double m_positionYOffset; - bool m_isVisible; bool m_isDirtyViewport; bool m_isDirtyAutoZoom; bool m_isPendingAnimation; @@ -213,6 +207,7 @@ private: bool m_isCompassAvailable; bool m_positionIsObsolete; + bool m_allowToFollowAfterObsoletePosition; bool m_needBlockAutoZoom; bool m_notFollowAfterPending;