From 4a83a820e2a8da9bf7d9033787787e99f3ef42e6 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Sat, 23 Apr 2022 12:41:13 +0300 Subject: [PATCH 1/9] [drape] Removed assert. Signed-off-by: Viktor Govako --- drape/overlay_tree.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drape/overlay_tree.cpp b/drape/overlay_tree.cpp index a14d1a9f61..b6086969e5 100644 --- a/drape/overlay_tree.cpp +++ b/drape/overlay_tree.cpp @@ -223,7 +223,8 @@ void OverlayTree::Add(ref_ptr handle) void OverlayTree::InsertHandle(ref_ptr handle, int currentRank, ref_ptr const & parentOverlay) { - ASSERT(handle->GetOverlayID().IsValid(), ()); + /// @todo Fires when updating country (delete-add) ?! + //ASSERT(handle->GetOverlayID().IsValid(), ()); ASSERT(IsNeedUpdate(), ()); #ifdef DEBUG_OVERLAYS_OUTPUT -- 2.45.3 From 70eb4eb71c319761b10187308111221583fa9bf3 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Sat, 23 Apr 2022 12:41:35 +0300 Subject: [PATCH 2/9] [tests] Minor renaming. Signed-off-by: Viktor Govako --- .../opening_hours_serdes_tests.cpp | 89 +++++++++---------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/routing/routing_tests/opening_hours_serdes_tests.cpp b/routing/routing_tests/opening_hours_serdes_tests.cpp index 59f9a6eee1..61e7fbc2fd 100644 --- a/routing/routing_tests/opening_hours_serdes_tests.cpp +++ b/routing/routing_tests/opening_hours_serdes_tests.cpp @@ -1,8 +1,7 @@ -#include "routing/routing_tests/index_graph_tools.hpp" - #include "testing/testing.hpp" #include "routing/opening_hours_serdes.hpp" +#include "routing/routing_tests/index_graph_tools.hpp" #include "coding/bit_streams.hpp" #include "coding/reader.hpp" @@ -15,16 +14,16 @@ #include #include +namespace opening_hours_serdes_tests +{ using namespace routing; using namespace routing_test; using Buffer = std::vector; -namespace +struct OHSerDesTestFixture { -struct BitReaderWriter -{ - BitReaderWriter() + OHSerDesTestFixture() : m_memWriter(m_buffer) , m_bitWriter(std::make_unique>>(m_memWriter)) { @@ -152,7 +151,7 @@ void TestMonth(osmoh::RuleSequence const & rule, Month startMonth, Month endMont 0 /* endDay */); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_EnableTests_1) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_EnableTests_1) { TEST(!IsEnabled(OpeningHoursSerDes::Header::Bits::Year), ()); Enable(OpeningHoursSerDes::Header::Bits::Year); @@ -167,7 +166,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_EnableTests_1) TEST(IsEnabled(OpeningHoursSerDes::Header::Bits::Minutes), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_EnableTests_2) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_EnableTests_2) { Enable(OpeningHoursSerDes::Header::Bits::Year); Enable(OpeningHoursSerDes::Header::Bits::WeekDay); @@ -185,7 +184,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_EnableTests_2) // Test on serialization ranges where start is later than end. // It is wrong but still possible data. -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_CannotSerialize) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_CannotSerialize) { Enable(OpeningHoursSerDes::Header::Bits::Year); Enable(OpeningHoursSerDes::Header::Bits::Month); @@ -193,7 +192,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_CannotSerialize) TEST(!Serialize("2020 May 20 - 2018 Nov 30"), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_YearOnly) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_YearOnly) { Enable(OpeningHoursSerDes::Header::Bits::Year); @@ -208,7 +207,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_YearOnly) TestYear(rule, 2019, 2090); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_YearAndMonthOnly) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_YearAndMonthOnly) { Enable(OpeningHoursSerDes::Header::Bits::Year); Enable(OpeningHoursSerDes::Header::Bits::Month); @@ -225,7 +224,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_YearAndMonthOnly) TestMonth(rule, 2019, Month::Apr, 10, 2051, Month::May, 19); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_1) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_Weekday_1) { Enable(OpeningHoursSerDes::Header::Bits::WeekDay); @@ -240,7 +239,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_1) TestWeekday(rule, Weekday::Monday, Weekday::Friday); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_2) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_Weekday_2) { Enable(OpeningHoursSerDes::Header::Bits::WeekDay); @@ -258,7 +257,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_2) TestWeekday(rule, Weekday::Friday, Weekday::Sunday); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_Hours_1) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_Weekday_Hours_1) { Enable(OpeningHoursSerDes::Header::Bits::WeekDay); Enable(OpeningHoursSerDes::Header::Bits::Hours); @@ -301,7 +300,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_Hours_1) } } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Off_SerDes_1_AndUsage) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_Off_SerDes_1_AndUsage) { SerializeEverything(); EnableAll(); @@ -324,7 +323,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Off_SerDes_1_AndUsage) TEST(oh.IsClosed(GetUnixtimeByDate(2020, Month::Feb, Weekday::Monday, 17 /* hh */, 30 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Off_SerDes_2) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_Off_SerDes_2) { SerializeEverything(); EnableAll(); @@ -360,7 +359,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Off_SerDes_2) TestModifier(rule, osmoh::RuleSequence::Modifier::Closed); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_OffJustOff) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_OffJustOff) { SerializeEverything(); EnableAll(); @@ -376,7 +375,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_OffJustOff) TestModifier(rule, osmoh::RuleSequence::Modifier::Closed); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_OffJustClosed) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_OffJustClosed) { SerializeEverything(); EnableAll(); @@ -392,7 +391,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_OffJustClosed) TestModifier(rule, osmoh::RuleSequence::Modifier::Closed); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Open) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_Open) { SerializeEverything(); EnableAll(); @@ -410,7 +409,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Open) TEST(oh.IsOpen(someMoment), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_TimeIsOver00) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_TimeIsOver00) { SerializeEverything(); EnableAll(); @@ -428,7 +427,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_TimeIsOver00) TEST(!oh.IsOpen(GetUnixtimeByDate(2020, Month::Feb, Weekday::Tuesday, 06 /* hh */, 30 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_DefaultOpen) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_DefaultOpen) { SerializeEverything(); EnableAll(); @@ -446,7 +445,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_DefaultOpen) TEST(!oh.IsOpen(GetUnixtimeByDate(2020, Month::Feb, Weekday::Sunday, 13 /* hh */, 30 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_SkipRuleOldYear) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_SkipRuleOldYear) { SerializeEverything(); EnableAll(); @@ -463,7 +462,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_SkipRuleOldYear) TestTime(rule, 7, 0, 17, 0); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_10_plus) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_10_plus) { SerializeEverything(); EnableAll(); @@ -487,7 +486,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_10_plus) TEST(!oh.IsOpen(GetUnixtimeByDate(2020, Month::Mar, Weekday::Saturday, 00 /* hh */, 30 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_24_7) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_24_7) { EnableAll(); @@ -498,7 +497,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_24_7) TEST(oh.IsTwentyFourHours(), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_1) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_1) { EnableAll(); @@ -513,7 +512,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditi TestMonth(rule, Month::Apr, 1, Month::Jun, 30); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_2) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_2) { EnableAll(); @@ -528,7 +527,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditi TestTime(rule, 22, 0, 6, 0); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_3) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_3) { EnableAll(); @@ -547,7 +546,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditi TestTime(rule, 21, 30, 7, 0); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_4) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_4) { EnableAll(); @@ -562,7 +561,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditi TestMonth(rule, Month::Apr, Month::Oct); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_5) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_5) { EnableAll(); @@ -582,7 +581,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditi TestTime(rule, 15, 0, 16, 0); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_6) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_ExamplesFromOsmAccessConditional_6) { SerializeEverything(); EnableAll(); @@ -602,7 +601,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_ExamplesFromOsmAccessConditi TestTime(rule, 11, 0, 18, 0); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_EnableForRouting_1) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_EnableForRouting_1) { EnableForRouting(); @@ -617,7 +616,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_EnableForRouting_1) TestWeekday(rule, Weekday::Sunday, Weekday::None); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_EnableForRouting_2) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_EnableForRouting_2) { EnableForRouting(); @@ -669,7 +668,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_EnableForRouting_2) TestTime(rule, 12, 0, 12, 30); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_WeekdayAndHolidayOff) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_WeekdayAndHolidayOff) { SerializeEverything(); EnableAll(); @@ -694,7 +693,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_WeekdayAndHolidayOff) TestModifier(rule, osmoh::RuleSequence::Modifier::Closed); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_WeekDay_OneDay) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_WeekDay_OneDay) { EnableAll(); @@ -710,7 +709,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_WeekDay_OneDay) TestTime(rule, 16, 0, 20, 0); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Hours_Usage_1) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_Hours_Usage_1) { EnableAll(); @@ -723,7 +722,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Hours_Usage_1) TEST(oh.IsClosed(GetUnixtimeByDate(2020, Month::Feb, Weekday::Monday, 07 /* hh */, 30 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_Usage_1) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_Weekday_Usage_1) { EnableAll(); @@ -736,7 +735,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_Usage_1) TEST(oh.IsOpen(GetUnixtimeByDate(2020, Month::Feb, Weekday::Wednesday, 17 /* hh */, 30 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_Usage_2) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_Weekday_Usage_2) { EnableAll(); @@ -751,7 +750,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_Usage_2) TEST(oh.IsClosed(GetUnixtimeByDate(2023, Month::Apr, Weekday::Saturday, 8 /* hh */, 30 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_Usage_3) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_Weekday_Usage_3) { EnableAll(); @@ -764,7 +763,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Weekday_Usage_3) TEST(oh.IsOpen(GetUnixtimeByDate(2020, Month::Feb, 7, 03 /* hh */, 30 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Month_Usage) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_Month_Usage) { EnableAll(); @@ -777,7 +776,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_Month_Usage) TEST(oh.IsClosed(GetUnixtimeByDate(2020, Month::Feb, 5, 17 /* hh */, 30 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_MonthDay_Usage) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_MonthDay_Usage) { EnableAll(); @@ -793,7 +792,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_MonthDay_Usage) TEST(oh.IsOpen(GetUnixtimeByDate(2021, Month::Mar, 26, 19 /* hh */, 00 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_MonthDayYear_Usage) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_MonthDayYear_Usage) { EnableAll(); @@ -809,7 +808,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_MonthDayYear_Usage) TEST(oh.IsClosed(GetUnixtimeByDate(2052, Month::Mar, 26, 19 /* hh */, 00 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_MonthHours_Usage) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_MonthHours_Usage) { EnableAll(); @@ -824,7 +823,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_MonthHours_Usage) TEST(oh.IsOpen(GetUnixtimeByDate(2020, Month::May, 6, 01 /* hh */, 32 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_InverseMonths_Usage_1) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_InverseMonths_Usage_1) { EnableAll(); @@ -841,7 +840,7 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_InverseMonths_Usage_1) TEST(!oh.IsOpen(GetUnixtimeByDate(2020, Month::Feb, 20, 20 /* hh */, 00 /* mm */)), ()); } -UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_InverseMonths_Usage_2) +UNIT_CLASS_TEST(OHSerDesTestFixture, OpeningHoursSerDes_InverseMonths_Usage_2) { EnableAll(); @@ -860,4 +859,4 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_InverseMonths_Usage_2) TEST(!oh.IsOpen(GetUnixtimeByDate(2020, Month::Apr, 20, 20 /* hh */, 00 /* mm */)), ()); TEST(!oh.IsOpen(GetUnixtimeByDate(2020, Month::May, 20, 20 /* hh */, 00 /* mm */)), ()); } -} // namespace +} // namespace opening_hours_serdes_tests -- 2.45.3 From 9abafe48f9a5dba0c63050f825bca7b02e2ed6a5 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Tue, 26 Apr 2022 06:54:20 +0300 Subject: [PATCH 3/9] [tests] Relaxed SmallMap benchmark. Signed-off-by: Viktor Govako --- base/base_tests/small_set_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/base_tests/small_set_test.cpp b/base/base_tests/small_set_test.cpp index 6d0382ac4d..c2ebb6d5b5 100644 --- a/base/base_tests/small_set_test.cpp +++ b/base/base_tests/small_set_test.cpp @@ -265,7 +265,7 @@ UNIT_TEST(SmallMap_Benchmark3) TEST_EQUAL(sum1, sum2, ()); TEST_EQUAL(sum1, sum3, ()); TEST_LESS(t2, t1, ()); - TEST_LESS(t3, t2, ()); + TEST(BenchmarkTimeLessOrNear(t3, t2, 0.05), (t3, t2)); LOG(LINFO, ("unordered_map time =", t1, "SmallMap time =", t2, "SmallMapBase time =", t3)); } #endif -- 2.45.3 From 44260ae3dfde048f4ad11f68c57aa1a6a5290d1c Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Sun, 24 Apr 2022 07:32:37 +0300 Subject: [PATCH 4/9] [android] Ignore possible false-positive location availability. Signed-off-by: Viktor Govako --- .../location/GoogleFusedLocationProvider.java | 11 ++++++----- .../mapswithme/maps/location/LocationHelper.java | 8 ++++++-- .../src/com/mapswithme/util/LocationUtils.java | 16 ++++++++++------ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/android/flavors/gms-enabled/com/mapswithme/maps/location/GoogleFusedLocationProvider.java b/android/flavors/gms-enabled/com/mapswithme/maps/location/GoogleFusedLocationProvider.java index e7d78d0d8b..8b7f63fac6 100644 --- a/android/flavors/gms-enabled/com/mapswithme/maps/location/GoogleFusedLocationProvider.java +++ b/android/flavors/gms-enabled/com/mapswithme/maps/location/GoogleFusedLocationProvider.java @@ -37,16 +37,17 @@ class GoogleFusedLocationProvider extends BaseLocationProvider // Documentation is inconsistent with the code: "returns null if no locations are available". // https://developers.google.com/android/reference/com/google/android/gms/location/LocationResult#getLastLocation() //noinspection ConstantConditions - if (location == null) - return; - mListener.onLocationChanged(location); + if (location != null) + mListener.onLocationChanged(location); } @Override public void onLocationAvailability(@NonNull LocationAvailability availability) { - if (!availability.isLocationAvailable()) - mListener.onLocationError(ERROR_GPS_OFF); + if (!availability.isLocationAvailable()) { + LOGGER.w(TAG, "isLocationAvailable returned false"); + //mListener.onLocationError(ERROR_GPS_OFF); + } } } diff --git a/android/src/com/mapswithme/maps/location/LocationHelper.java b/android/src/com/mapswithme/maps/location/LocationHelper.java index 460dc8ad59..ade44eb630 100644 --- a/android/src/com/mapswithme/maps/location/LocationHelper.java +++ b/android/src/com/mapswithme/maps/location/LocationHelper.java @@ -319,11 +319,15 @@ public enum LocationHelper implements Initializable, AppBackgroundTrack public void onLocationError(int errCode) { mLogger.d(TAG, "onLocationError(): " + errCode); - if (errCode == ERROR_NOT_SUPPORTED && !(mLocationProvider instanceof AndroidNativeProvider)) + if (errCode == ERROR_NOT_SUPPORTED && + LocationUtils.areLocationServicesTurnedOn(mContext) && + !(mLocationProvider instanceof AndroidNativeProvider)) { - // Try to downgrade to native provider first before notifying the user. + // If location service is enabled, try to downgrade to the native provider first + // and restart the service before notifying the user. mLogger.d(TAG, "Downgrading to use native provider"); mLocationProvider = new AndroidNativeProvider(mContext, this); + restart(); return; } diff --git a/android/src/com/mapswithme/util/LocationUtils.java b/android/src/com/mapswithme/util/LocationUtils.java index 88084d1878..6d37a6c854 100644 --- a/android/src/com/mapswithme/util/LocationUtils.java +++ b/android/src/com/mapswithme/util/LocationUtils.java @@ -5,6 +5,7 @@ import android.content.ContentResolver; import android.content.Context; import android.location.Location; import android.location.LocationManager; +import android.os.Build; import android.provider.Settings; import android.view.Surface; @@ -99,17 +100,20 @@ public class LocationUtils return newLocation.getAccuracy() < lastAccuracy; } - - @SuppressLint("InlinedApi") - @SuppressWarnings("deprecation") public static boolean areLocationServicesTurnedOn(@NonNull Context context) { - final ContentResolver resolver = context.getContentResolver(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) + { + final LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + return lm.isLocationEnabled(); + } + try { - return Settings.Secure.getInt(resolver, Settings.Secure.LOCATION_MODE) + return Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE) != Settings.Secure.LOCATION_MODE_OFF; - } catch (Settings.SettingNotFoundException e) + } + catch (Settings.SettingNotFoundException e) { e.printStackTrace(); return false; -- 2.45.3 From 7bb934443e080bcfe063508bb30e62718293b630 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Tue, 26 Apr 2022 19:11:16 +0300 Subject: [PATCH 5/9] [android][drape] Cleanup my-position-mode startup logic. Signed-off-by: Viktor Govako --- android/jni/com/mapswithme/maps/Framework.cpp | 25 ++-------- android/jni/com/mapswithme/maps/Framework.hpp | 7 +-- .../jni/com/mapswithme/maps/LocationState.cpp | 2 - .../src/com/mapswithme/maps/MwmActivity.java | 2 +- .../maps/location/LocationHelper.java | 40 +++++++-------- drape_frontend/drape_engine.cpp | 43 ++++++++++------ drape_frontend/drape_engine.hpp | 8 +-- drape_frontend/frontend_renderer.hpp | 2 + drape_frontend/my_position_controller.cpp | 50 ++++++++++++------- drape_frontend/my_position_controller.hpp | 3 +- .../Maps/Core/Location/MWMLocationHelpers.h | 12 +---- iphone/Maps/Core/Routing/MWMRouter.mm | 19 ++++--- map/framework.cpp | 34 ++++++------- map/framework.hpp | 10 +--- platform/settings.cpp | 7 +-- platform/settings.hpp | 6 +-- 16 files changed, 132 insertions(+), 138 deletions(-) diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 5563e46a8b..0bdf3ac9b5 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -106,8 +106,6 @@ enum MultiTouchAction Framework::Framework() : m_lastCompass(0.0) , m_isSurfaceDestroyed(false) - , m_currentMode(location::PendingPosition) - , m_isCurrentModeInitialized(false) , m_isChoosePositionMode(false) { m_work.GetTrafficManager().SetStateListener(bind(&Framework::TrafficStateChanged, this, _1)); @@ -234,8 +232,6 @@ bool Framework::CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi p.m_surfaceHeight = oglFactory->GetHeight(); } p.m_visualScale = static_cast(dp::VisualScale(densityDpi)); - p.m_hasMyPositionState = m_isCurrentModeInitialized; - p.m_initialMyPositionState = m_currentMode; p.m_isChoosePositionMode = m_isChoosePositionMode; p.m_hints.m_isFirstLaunch = firstLaunch; p.m_hints.m_isLaunchByDeepLink = launchByDeepLink; @@ -253,7 +249,7 @@ bool Framework::CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi return true; } -bool Framework::IsDrapeEngineCreated() +bool Framework::IsDrapeEngineCreated() const { return m_work.IsDrapeEngineCreated(); } @@ -642,23 +638,12 @@ void Framework::SetMyPositionModeListener(location::TMyPositionModeChanged const m_myPositionModeSignal = fn; } -location::EMyPositionMode Framework::GetMyPositionMode() +location::EMyPositionMode Framework::GetMyPositionMode() const { - if (!m_isCurrentModeInitialized) - { - if (!settings::Get(settings::kLocationStateMode, m_currentMode)) - m_currentMode = location::NotFollowNoPosition; + // No need in assertion here, return location::PendingPosition if no engine created. + //ASSERT(IsDrapeEngineCreated(), ()); - m_isCurrentModeInitialized = true; - } - - return m_currentMode; -} - -void Framework::OnMyPositionModeChanged(location::EMyPositionMode mode) -{ - m_currentMode = mode; - m_isCurrentModeInitialized = true; + return m_work.GetMyPositionMode(); } void Framework::SwitchMyPositionNextMode() diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp index ad693a0632..69974af199 100644 --- a/android/jni/com/mapswithme/maps/Framework.hpp +++ b/android/jni/com/mapswithme/maps/Framework.hpp @@ -70,8 +70,6 @@ namespace android void MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive); location::TMyPositionModeChanged m_myPositionModeSignal; - location::EMyPositionMode m_currentMode; - bool m_isCurrentModeInitialized; TrafficManager::TrafficStateChangedFn m_onTrafficStateChangedFn; TransitReadManager::TransitStateChangedFn m_onTransitStateChangedFn; @@ -93,7 +91,7 @@ namespace android bool CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi, bool firstLaunch, bool launchByDeepLink, uint32_t appVersionCode); - bool IsDrapeEngineCreated(); + bool IsDrapeEngineCreated() const; bool DestroySurfaceOnDetach(); void DetachSurface(bool destroySurface); bool AttachSurface(JNIEnv * env, jobject jSurface); @@ -160,8 +158,7 @@ namespace android // std::string GetOutdatedCountriesString(); void SetMyPositionModeListener(location::TMyPositionModeChanged const & fn); - location::EMyPositionMode GetMyPositionMode(); - void OnMyPositionModeChanged(location::EMyPositionMode mode); + location::EMyPositionMode GetMyPositionMode() const; void SwitchMyPositionNextMode(); void SetTrafficStateListener(TrafficManager::TrafficStateChangedFn const & fn); diff --git a/android/jni/com/mapswithme/maps/LocationState.cpp b/android/jni/com/mapswithme/maps/LocationState.cpp index 4942acf310..7d8e4b851d 100644 --- a/android/jni/com/mapswithme/maps/LocationState.cpp +++ b/android/jni/com/mapswithme/maps/LocationState.cpp @@ -10,8 +10,6 @@ extern "C" static void LocationStateModeChanged(location::EMyPositionMode mode, std::shared_ptr const & listener) { - g_framework->OnMyPositionModeChanged(mode); - JNIEnv * env = jni::GetEnv(); env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener.get(), "onMyPositionModeChanged", "(I)V"), static_cast(mode)); diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java index 4b376c1792..02f7eea910 100644 --- a/android/src/com/mapswithme/maps/MwmActivity.java +++ b/android/src/com/mapswithme/maps/MwmActivity.java @@ -124,7 +124,7 @@ public class MwmActivity extends BaseMwmFragmentActivity NoConnectionListener, MapWidgetOffsetsProvider { - private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC); + private final Logger mLogger = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC); private static final String TAG = MwmActivity.class.getSimpleName(); public static final String EXTRA_TASK = "map_task"; diff --git a/android/src/com/mapswithme/maps/location/LocationHelper.java b/android/src/com/mapswithme/maps/location/LocationHelper.java index ade44eb630..fde5b43104 100644 --- a/android/src/com/mapswithme/maps/location/LocationHelper.java +++ b/android/src/com/mapswithme/maps/location/LocationHelper.java @@ -154,12 +154,14 @@ public enum LocationHelper implements Initializable, AppBackgroundTrack }; @SuppressWarnings("FieldCanBeLocal") - private final LocationState.LocationPendingTimeoutListener mLocationPendingTimeoutListener = - () -> { - stop(); - if (PermissionsUtils.isLocationGranted(mContext) && LocationUtils.areLocationServicesTurnedOn(mContext)) - notifyLocationNotFound(); - }; + private final LocationState.LocationPendingTimeoutListener mLocationPendingTimeoutListener = () -> { + if (mActive) + { + stop(); + if (PermissionsUtils.isLocationGranted(mContext) && LocationUtils.areLocationServicesTurnedOn(mContext)) + notifyLocationNotFound(); + } + }; @Override public void initialize(@NotNull Context context) @@ -246,7 +248,7 @@ public enum LocationHelper implements Initializable, AppBackgroundTrack mReceiverRegistered = false; } - start(); + initialStart(); } else { @@ -440,11 +442,16 @@ public enum LocationHelper implements Initializable, AppBackgroundTrack */ public void restart() { - mLogger.i(TAG, "restart()"); stop(); start(); } + private void initialStart() + { + if (LocationState.nativeGetMode() != LocationState.NOT_FOLLOW_NO_POSITION) + start(); + } + /** * Adds the {@link #mCoreLocationListener} to listen location updates and notify UI. * Notifies about {@link #ERROR_DENIED} if there are no enabled location providers. @@ -455,7 +462,7 @@ public enum LocationHelper implements Initializable, AppBackgroundTrack { if (mActive) { - mLogger.i(TAG, "Provider '" + mLocationProvider + "' is already started"); + mLogger.w(TAG, "Provider '" + mLocationProvider + "' is already started"); return; } @@ -492,7 +499,7 @@ public enum LocationHelper implements Initializable, AppBackgroundTrack mLogger.i(TAG, "stop()"); if (!mActive) { - mLogger.i(TAG, "Provider '" + mLocationProvider + "' is already stopped"); + mLogger.w(TAG, "Provider '" + mLocationProvider + "' is already stopped"); return; } @@ -553,7 +560,7 @@ public enum LocationHelper implements Initializable, AppBackgroundTrack } else { - restart(); + initialStart(); } } @@ -597,9 +604,6 @@ public enum LocationHelper implements Initializable, AppBackgroundTrack mInFirstRun = false; - if (getMyPositionMode() != LocationState.NOT_FOLLOW_NO_POSITION) - throw new AssertionError("My position mode must be equal NOT_FOLLOW_NO_POSITION"); - // If there is a location we need just to pass it to the listeners, so that // my position state machine will be switched to the FOLLOW state. if (mSavedLocation != null) @@ -610,12 +614,8 @@ public enum LocationHelper implements Initializable, AppBackgroundTrack return; } - // If the location hasn't been obtained yet we need to switch to the next mode and wait for locations. - // Otherwise, try to restart location updates polling. - if (mActive) - switchToNextMode(); - else - restart(); + // Restart location service to show alert dialog if any location error. + restart(); } @Nullable diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index f792aa3d40..9d8c5691e9 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -1,7 +1,7 @@ #include "drape_frontend/drape_engine.hpp" -#include "drape_frontend/message_subclasses.hpp" #include "drape_frontend/gui/drape_gui.hpp" +#include "drape_frontend/message_subclasses.hpp" #include "drape_frontend/my_position_controller.hpp" #include "drape_frontend/visual_params.hpp" @@ -13,10 +13,16 @@ #include -using namespace std::placeholders; - namespace df { +using namespace std::placeholders; + +namespace +{ +std::string const kLocationStateMode = "LastLocationStateMode"; +std::string const kLastEnterBackground = "LastEnterBackground"; +} + DrapeEngine::DrapeEngine(Params && params) : m_myPositionModeChanged(std::move(params.m_myPositionModeChanged)) , m_viewport(std::move(params.m_viewport)) @@ -34,24 +40,20 @@ DrapeEngine::DrapeEngine(Params && params) m_threadCommutator = make_unique_dp(); m_requestedTiles = make_unique_dp(); - location::EMyPositionMode mode = params.m_initialMyPositionMode.first; - if (!params.m_initialMyPositionMode.second && !settings::Get(settings::kLocationStateMode, mode)) - { - mode = location::PendingPosition; - } - else if (mode == location::FollowAndRotate) + using namespace location; + EMyPositionMode mode = PendingPosition; + if (settings::Get(kLocationStateMode, mode) && mode == FollowAndRotate) { // If the screen rect setting in follow and rotate mode is missing or invalid, it could cause // invalid animations, so the follow and rotate mode should be discarded. m2::AnyRectD rect; if (!(settings::Get("ScreenClipRect", rect) && df::GetWorldRect().IsRectInside(rect.GetGlobalRect()))) - mode = location::Follow; + mode = Follow; } double timeInBackground = 0.0; - double lastEnterBackground = 0.0; - if (settings::Get("LastEnterBackground", lastEnterBackground)) - timeInBackground = base::Timer::LocalTime() - lastEnterBackground; + if (settings::Get(kLastEnterBackground, timeInBackground)) + timeInBackground = base::Timer::LocalTime() - timeInBackground; std::vector effects; @@ -448,11 +450,16 @@ void DrapeEngine::ModelViewChanged(ScreenBase const & screen) void DrapeEngine::MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive) { - settings::Set(settings::kLocationStateMode, mode); - if (m_myPositionModeChanged != nullptr) + settings::Set(kLocationStateMode, mode); + if (m_myPositionModeChanged) m_myPositionModeChanged(mode, routingActive); } +location::EMyPositionMode DrapeEngine::GetMyPositionMode() const +{ + return m_frontend->GetMyPositionMode(); +} + void DrapeEngine::TapEvent(TapInfo const & tapInfo) { if (m_tapEventInfoHandler != nullptr) @@ -724,8 +731,9 @@ void DrapeEngine::SetKineticScrollEnabled(bool enabled) MessagePriority::Normal); } -void DrapeEngine::OnEnterForeground(double backgroundTime) +void DrapeEngine::OnEnterForeground() { + double const backgroundTime = base::Timer::LocalTime() - m_startBackgroundTime; m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(backgroundTime), MessagePriority::High); @@ -733,6 +741,9 @@ void DrapeEngine::OnEnterForeground(double backgroundTime) void DrapeEngine::OnEnterBackground() { + m_startBackgroundTime = base::Timer::LocalTime(); + settings::Set(kLastEnterBackground, m_startBackgroundTime); + m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(), MessagePriority::High); diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 7f1f3eaaec..b7b5b9019f 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -59,7 +59,6 @@ public: double vs, double fontsScaleFactor, gui::TWidgetsInitInfo && info, - std::pair const & initialMyPositionMode, location::TMyPositionModeChanged && myPositionModeChanged, bool allow3dBuildings, bool trafficEnabled, @@ -80,7 +79,6 @@ public: , m_vs(vs) , m_fontsScaleFactor(fontsScaleFactor) , m_info(std::move(info)) - , m_initialMyPositionMode(initialMyPositionMode) , m_myPositionModeChanged(std::move(myPositionModeChanged)) , m_allow3dBuildings(allow3dBuildings) , m_trafficEnabled(trafficEnabled) @@ -207,7 +205,7 @@ public: void SetKineticScrollEnabled(bool enabled); - void OnEnterForeground(double backgroundTime); + void OnEnterForeground(); void OnEnterBackground(); using TRequestSymbolsSizeCallback = std::function &&)>; @@ -250,6 +248,8 @@ public: void UpdateVisualScale(double vs, bool needStopRendering); void UpdateMyPositionRoutingOffset(bool useDefault, int offsetY); + location::EMyPositionMode GetMyPositionMode() const; + private: void AddUserEvent(drape_ptr && e); void PostUserEvent(drape_ptr && e); @@ -291,6 +291,8 @@ private: std::atomic m_drapeIdGenerator = 0; + double m_startBackgroundTime = 0; + friend class DrapeApi; }; } // namespace df diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 1d61bce6ad..a84d763f1c 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -150,6 +150,8 @@ public: drape_ptr const & GetScenarioManager() const; + location::EMyPositionMode GetMyPositionMode() const { return m_myPositionController->GetCurrentMode(); } + protected: void AcceptMessage(ref_ptr message) override; std::unique_ptr CreateRoutine() override; diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index ded3457614..695b393273 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -118,10 +118,6 @@ bool IsModeChangeViewport(location::EMyPositionMode mode) MyPositionController::MyPositionController(Params && params, ref_ptr notifier) : m_notifier(notifier) - , m_mode(params.m_isRoutingActive || df::IsModeChangeViewport(params.m_initMode) - ? location::PendingPosition - : location::NotFollowNoPosition) - , m_desiredInitMode(params.m_initMode) , m_modeChangeCallback(std::move(params.m_myPositionModeCallback)) , m_hints(params.m_hints) , m_isInRouting(params.m_isRoutingActive) @@ -153,22 +149,35 @@ MyPositionController::MyPositionController(Params && params, ref_ptr= kMaxTimeInBackgroundSec) { - m_mode = location::PendingPosition; - m_desiredInitMode = location::Follow; + m_mode = PendingPosition; + m_desiredInitMode = Follow; + } + else + { + // Restore PendingPosition mode (and start location service on platform side accordingly) + // if we have routing mode or FollowXXX desired mode (usually loaded from settings). + m_desiredInitMode = params.m_initMode; + m_mode = (params.m_isRoutingActive || df::IsModeChangeViewport(m_desiredInitMode)) ? + PendingPosition : NotFollowNoPosition; } - if (m_modeChangeCallback != nullptr) + m_pendingStarted = (m_mode == PendingPosition); + + if (m_modeChangeCallback) m_modeChangeCallback(m_mode, m_isInRouting); } @@ -437,15 +446,22 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool 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 current mode must be - // NotFollowNoPosition, new mode will be NotFollow to prevent spontaneous map snapping. + // If the position was never assigned, the new mode will be the desired one except next cases: location::EMyPositionMode newMode = m_desiredInitMode; if (m_mode == location::NotFollowNoPosition) { + // We touch the map during the PendingPosition mode and current mode was converted into NotFollowNoPosition. + // New mode will be NotFollow to prevent spontaneous map snapping. ResetRoutingNotFollowTimer(); newMode = location::NotFollow; } + else if (m_mode == location::PendingPosition && newMode < location::Follow) + { + // This is the first user location request (button touch) after controller's initialization + // with some previous not Follow state. New mode will be Follow to move on current position. + newMode = location::Follow; + } + ChangeMode(newMode); if (!m_hints.m_isFirstLaunch || !AnimationSystem::Instance().AnimationExists(Animation::Object::MapPlane)) @@ -645,7 +661,7 @@ void MyPositionController::ChangeMode(location::EMyPositionMode newMode) } m_mode = newMode; - if (m_modeChangeCallback != nullptr) + if (m_modeChangeCallback) m_modeChangeCallback(m_mode, m_isInRouting); } @@ -653,7 +669,7 @@ bool MyPositionController::IsWaitingForLocation() const { if (m_mode == location::NotFollowNoPosition) return false; - + if (!m_isPositionAssigned) return true; @@ -742,7 +758,7 @@ void MyPositionController::UpdateViewport(int zoomLevel) { if (IsWaitingForLocation()) return; - + if (m_mode == location::Follow) { ChangeModelView(m_position, zoomLevel); @@ -759,7 +775,7 @@ m2::PointD MyPositionController::GetRotationPixelCenter() const { if (m_mode == location::Follow) return m_visiblePixelRect.Center(); - + if (m_mode == location::FollowAndRotate) return m_isInRouting ? GetRoutingRotationPixelCenter() : m_visiblePixelRect.Center(); diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index d30c288592..81b62255a5 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -114,6 +114,7 @@ public: void StopLocationFollow(); void NextMode(ScreenBase const & screen); void LoseLocation(); + location::EMyPositionMode GetCurrentMode() const { return m_mode; } void OnEnterForeground(double backgroundTime); void OnEnterBackground(); @@ -191,7 +192,7 @@ private: base::Timer m_lastGPSBearingTimer; base::Timer m_pendingTimer; - bool m_pendingStarted = true; + bool m_pendingStarted; base::Timer m_routingNotFollowTimer; bool m_blockRoutingNotFollowTimer = false; base::Timer m_blockAutoZoomTimer; diff --git a/iphone/Maps/Core/Location/MWMLocationHelpers.h b/iphone/Maps/Core/Location/MWMLocationHelpers.h index ddeed6557e..abb31343bf 100644 --- a/iphone/Maps/Core/Location/MWMLocationHelpers.h +++ b/iphone/Maps/Core/Location/MWMLocationHelpers.h @@ -3,7 +3,6 @@ #include "platform/localization.hpp" #include "platform/location.hpp" #include "platform/measurement_utils.hpp" -#include "platform/settings.hpp" #include "geometry/mercator.hpp" @@ -18,15 +17,6 @@ static inline NSString * formattedDistance(double const & meters) { return @(measurement_utils::FormatDistanceWithLocalization(meters, localizedUnits.m_high, localizedUnits.m_low).c_str()); } -static inline BOOL isMyPositionPendingOrNoPosition() -{ - location::EMyPositionMode mode; - if (!settings::Get(settings::kLocationStateMode, mode)) - return true; - return mode == location::EMyPositionMode::PendingPosition || - mode == location::EMyPositionMode::NotFollowNoPosition; -} - static inline ms::LatLon ToLatLon(m2::PointD const & p) { return mercator::ToLatLon(p); } static inline m2::PointD ToMercator(CLLocationCoordinate2D const & l) @@ -46,4 +36,4 @@ static inline MWMMyPositionMode mwmMyPositionMode(location::EMyPositionMode mode case location::EMyPositionMode::FollowAndRotate: return MWMMyPositionModeFollowAndRotate; } } -} // namespace MWMLocationHelpers +} // namespace location_helpers diff --git a/iphone/Maps/Core/Routing/MWMRouter.mm b/iphone/Maps/Core/Routing/MWMRouter.mm index 87a5476db7..a3e9e4f694 100644 --- a/iphone/Maps/Core/Routing/MWMRouter.mm +++ b/iphone/Maps/Core/Routing/MWMRouter.mm @@ -279,20 +279,23 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm auto const doStart = ^{ auto &rm = GetFramework().GetRoutingManager(); auto const routePoints = rm.GetRoutePoints(); - if (routePoints.size() >= 2) { + if (routePoints.size() >= 2) + { auto p1 = [[MWMRoutePoint alloc] initWithRouteMarkData:routePoints.front()]; auto p2 = [[MWMRoutePoint alloc] initWithRouteMarkData:routePoints.back()]; - if (p1.isMyPosition && [MWMLocationManager lastLocation]) { + CLLocation *lastLocation = [MWMLocationManager lastLocation]; + if (p1.isMyPosition && lastLocation) + { rm.FollowRoute(); [[MWMMapViewControlsManager manager] onRouteStart]; [MWMThemeManager setAutoUpdates:YES]; - } else { - MWMAlertViewController *alertController = [MWMAlertViewController activeAlertController]; - CLLocation *lastLocation = [MWMLocationManager lastLocation]; - BOOL const needToRebuild = - lastLocation && !location_helpers::isMyPositionPendingOrNoPosition() && !p2.isMyPosition; - [alertController + } + else + { + BOOL const needToRebuild = lastLocation && [MWMLocationManager isStarted] && !p2.isMyPosition; + + [[MWMAlertViewController activeAlertController] presentPoint2PointAlertWithOkBlock:^{ [self buildFromPoint:[[MWMRoutePoint alloc] initWithLastLocationAndType:MWMRoutePointTypeStart intermediateIndex:0] diff --git a/map/framework.cpp b/map/framework.cpp index 12b2e434be..ac7411fcf1 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -104,7 +104,6 @@ using namespace location; using namespace routing; using namespace storage; -using namespace std::chrono; using namespace std::placeholders; using namespace std; @@ -237,6 +236,11 @@ void Framework::SetMyPositionPendingTimeoutListener(df::DrapeEngine::UserPositio m_myPositionPendingTimeoutListener = move(fn); } +EMyPositionMode Framework::GetMyPositionMode() const +{ + return m_drapeEngine ? m_drapeEngine->GetMyPositionMode() : PendingPosition; +} + TrafficManager & Framework::GetTrafficManager() { return m_trafficManager; @@ -1141,10 +1145,7 @@ void Framework::MemoryWarning() void Framework::EnterBackground() { - m_startBackgroundTime = base::Timer::LocalTime(); - settings::Set("LastEnterBackground", m_startBackgroundTime); - - if (m_drapeEngine != nullptr) + if (m_drapeEngine) m_drapeEngine->OnEnterBackground(); SaveViewport(); @@ -1161,12 +1162,8 @@ void Framework::EnterBackground() void Framework::EnterForeground() { - m_startForegroundTime = base::Timer::LocalTime(); - if (m_drapeEngine != nullptr && m_startBackgroundTime != 0.0) - { - auto const secondsInBackground = m_startForegroundTime - m_startBackgroundTime; - m_drapeEngine->OnEnterForeground(secondsInBackground); - } + if (m_drapeEngine) + m_drapeEngine->OnEnterForeground(); m_trafficManager.OnEnterForeground(); } @@ -1507,7 +1504,6 @@ void Framework::CreateDrapeEngine(ref_ptr contextFac df::MapDataProvider(move(idReadFn), move(featureReadFn), move(isCountryLoadedByNameFn), move(updateCurrentCountryFn)), params.m_hints, params.m_visualScale, fontsScaleFactor, move(params.m_widgetsInitInfo), - make_pair(params.m_initialMyPositionState, params.m_hasMyPositionState), move(myPositionModeChangedFn), allow3dBuildings, trafficEnabled, isolinesEnabled, params.m_isChoosePositionMode, params.m_isChoosePositionMode, GetSelectedFeatureTriangles(), @@ -1522,19 +1518,22 @@ void Framework::CreateDrapeEngine(ref_ptr contextFac }); m_drapeEngine->SetTapEventInfoListener([this](df::TapInfo const & tapInfo) { - GetPlatform().RunTask(Platform::Thread::Gui, [this, tapInfo]() { + GetPlatform().RunTask(Platform::Thread::Gui, [this, tapInfo]() + { OnTapEvent(place_page::BuildInfo(tapInfo)); }); }); m_drapeEngine->SetUserPositionListener([this](m2::PointD const & position, bool hasPosition) { - GetPlatform().RunTask(Platform::Thread::Gui, [this, position, hasPosition](){ + GetPlatform().RunTask(Platform::Thread::Gui, [this, position, hasPosition]() + { OnUserPositionChanged(position, hasPosition); }); }); m_drapeEngine->SetUserPositionPendingTimeoutListener([this]() { - GetPlatform().RunTask(Platform::Thread::Gui, [this](){ + GetPlatform().RunTask(Platform::Thread::Gui, [this]() + { if (m_myPositionPendingTimeoutListener) m_myPositionPendingTimeoutListener(); }); @@ -3237,11 +3236,6 @@ bool Framework::HaveTransit(m2::PointD const & pt) const return handle.GetValue()->m_cont.IsExist(TRANSIT_FILE_TAG); } -double Framework::GetLastBackgroundTime() const -{ - return m_startBackgroundTime; -} - void Framework::OnPowerFacilityChanged(power_management::Facility const facility, bool enabled) { if (facility == power_management::Facility::PerspectiveView || diff --git a/map/framework.hpp b/map/framework.hpp index 9ea0ca7b0c..bad029ccc7 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -177,10 +177,6 @@ protected: drape_ptr m_drapeEngine; - // Time in seconds. - double m_startForegroundTime = 0.0; - double m_startBackgroundTime = 0.0; - StorageDownloadingPolicy m_storageDownloadingPolicy; storage::Storage m_storage; bool m_enabledDiffs; @@ -400,6 +396,8 @@ public: void SetMyPositionModeListener(location::TMyPositionModeChanged && fn); void SetMyPositionPendingTimeoutListener(df::DrapeEngine::UserPositionPendingTimeoutHandler && fn); + location::EMyPositionMode GetMyPositionMode() const; + private: void OnUserPositionChanged(m2::PointD const & position, bool hasPosition); @@ -412,9 +410,6 @@ public: int m_surfaceHeight = 0; gui::TWidgetsInitInfo m_widgetsInitInfo; - bool m_hasMyPositionState = false; - location::EMyPositionMode m_initialMyPositionState = location::PendingPosition; - bool m_isChoosePositionMode = false; df::Hints m_hints; }; @@ -741,7 +736,6 @@ private: public: // TipsApi::Delegate override. bool HaveTransit(m2::PointD const & pt) const; - double GetLastBackgroundTime() const; power_management::PowerManager & GetPowerManager() { return m_powerManager; } diff --git a/platform/settings.cpp b/platform/settings.cpp index aa8f91d187..2e09afc2f4 100644 --- a/platform/settings.cpp +++ b/platform/settings.cpp @@ -16,11 +16,10 @@ #include #include -using namespace std; - namespace settings { -char const * kLocationStateMode = "LastLocationStateMode"; +using namespace std; + char const * kMeasurementUnits = "Units"; StringStorage::StringStorage() : StringStorageBase(GetPlatform().SettingsPathForFile(SETTINGS_FILE_NAME)) {} @@ -367,6 +366,7 @@ bool IsFirstLaunchForDate(int date) } } // namespace settings +/* namespace marketing { Settings::Settings() : platform::StringStorageBase(GetPlatform().SettingsPathForFile(MARKETING_SETTINGS_FILE_NAME)) {} @@ -378,3 +378,4 @@ Settings & Settings::Instance() return instance; } } // namespace marketing +*/ diff --git a/platform/settings.hpp b/platform/settings.hpp index 2ff9a6c10a..4cfb6ae5c5 100644 --- a/platform/settings.hpp +++ b/platform/settings.hpp @@ -8,8 +8,6 @@ namespace settings { -/// Current location state mode. @See location::EMyPositionMode. -extern char const * kLocationStateMode; /// Metric or Feet. extern char const * kMeasurementUnits; @@ -57,8 +55,9 @@ inline void Clear() { StringStorage::Instance().Clear(); } /// Use this function for running some stuff once according to date. /// @param[in] date Current date in format yymmdd. bool IsFirstLaunchForDate(int date); -} +} // namespace settings +/* namespace marketing { class Settings : public platform::StringStorageBase @@ -82,3 +81,4 @@ private: Settings(); }; } // namespace marketing +*/ -- 2.45.3 From 130caabdb63165a0386a483de50f373fb067dd3d Mon Sep 17 00:00:00 2001 From: Konstantin Pastbin Date: Fri, 22 Apr 2022 20:29:50 +0300 Subject: [PATCH 6/9] [storage] Removed unused GetWritableStorageSpace(), add debug logging Signed-off-by: Konstantin Pastbin --- platform/platform.hpp | 1 - platform/platform_unix_impl.cpp | 20 +++----------------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/platform/platform.hpp b/platform/platform.hpp index 8afb79efa4..21796d0dca 100644 --- a/platform/platform.hpp +++ b/platform/platform.hpp @@ -243,7 +243,6 @@ public: NOT_ENOUGH_SPACE }; TStorageStatus GetWritableStorageStatus(uint64_t neededSize) const; - uint64_t GetWritableStorageSpace() const; // Please note, that number of active cores can vary at runtime. // DO NOT assume for the same return value between calls. diff --git a/platform/platform_unix_impl.cpp b/platform/platform_unix_impl.cpp index af77d44b55..a5bf894b67 100644 --- a/platform/platform_unix_impl.cpp +++ b/platform/platform_unix_impl.cpp @@ -124,28 +124,14 @@ Platform::TStorageStatus Platform::GetWritableStorageStatus(uint64_t neededSize) return STORAGE_DISCONNECTED; } - /// @todo May be add additional storage space. - if (st.f_bsize * st.f_bavail < neededSize) + auto const availableBytes = st.f_bsize * st.f_bavail; + LOG(LDEBUG, ("Free space check: requested =", neededSize, "; available =", availableBytes)); + if (availableBytes < neededSize) return NOT_ENOUGH_SPACE; return STORAGE_OK; } -uint64_t Platform::GetWritableStorageSpace() const -{ - struct statfs st; - int const ret = statfs(m_writableDir.c_str(), &st); - - LOG(LDEBUG, ("statfs return =", ret, - "; block size =", st.f_bsize, - "; blocks available =", st.f_bavail)); - - if (ret != 0) - LOG(LERROR, ("Path:", m_writableDir, "statfs error:", ErrnoToError())); - - return (ret != 0) ? 0 : st.f_bsize * st.f_bavail; -} - namespace pl { -- 2.45.3 From eef2d289fa3de5478915de73b0993ff107fd40b6 Mon Sep 17 00:00:00 2001 From: Konstantin Pastbin Date: Fri, 22 Apr 2022 20:41:10 +0300 Subject: [PATCH 7/9] [android] Make 'Save maps to' menu item always visible Signed-off-by: Konstantin Pastbin --- .../maps/settings/SettingsPrefsFragment.java | 54 ------------------- .../maps/settings/StoragePathManager.java | 13 +---- 2 files changed, 1 insertion(+), 66 deletions(-) diff --git a/android/src/com/mapswithme/maps/settings/SettingsPrefsFragment.java b/android/src/com/mapswithme/maps/settings/SettingsPrefsFragment.java index 7b758dbaa1..acf595afcd 100644 --- a/android/src/com/mapswithme/maps/settings/SettingsPrefsFragment.java +++ b/android/src/com/mapswithme/maps/settings/SettingsPrefsFragment.java @@ -1,6 +1,5 @@ package com.mapswithme.maps.settings; -import android.app.Activity; import android.content.Context; import android.content.Intent; import android.net.Uri; @@ -51,8 +50,6 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment { private static final int REQUEST_INSTALL_DATA = 1; - @NonNull - private final StoragePathManager mPathManager = new StoragePathManager(); @Nullable private Preference mStoragePref; @@ -71,31 +68,6 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment private LanguageData mCurrentLanguage; private String mSelectedLanguage; - private boolean singleStorageOnly() - { - return !mPathManager.hasMoreThanOneStorage(); - } - - private void updateStoragePrefs() - { - Preference old = findPreference(getString(R.string.pref_storage)); - - if (singleStorageOnly()) - { - if (old != null) - { - removePreference(getString(R.string.pref_settings_general), old); - } - } - else - { - if (old == null && mStoragePref != null) - { - getPreferenceScreen().addPreference(mStoragePref); - } - } - } - private final Preference.OnPreferenceChangeListener mEnabledListener = new Preference.OnPreferenceChangeListener() { @Override @@ -285,7 +257,6 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment mLangInfo = findPreference(getString(R.string.pref_tts_info)); mLangInfoLink = findPreference(getString(R.string.pref_tts_info_link)); initLangInfoLink(); - updateStoragePrefs(); initStoragePrefCallbacks(); initMeasureUnitsPrefsCallbacks(); initZoomPrefsCallbacks(); @@ -820,31 +791,6 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment category.removePreference(preference); } - @Override - public void onAttach(Context context) - { - super.onAttach(context); - - if (!(context instanceof Activity)) - return; - - mPathManager.startExternalStorageWatching((Activity) context, new StoragePathManager.OnStorageListChangedListener() - { - @Override - public void onStorageListChanged(List storageItems, int currentStorageIndex) - { - updateStoragePrefs(); - } - }, null); - } - - @Override - public void onDetach() - { - super.onDetach(); - mPathManager.stopExternalStorageWatching(); - } - enum ThemeMode { DEFAULT(R.string.theme_default), diff --git a/android/src/com/mapswithme/maps/settings/StoragePathManager.java b/android/src/com/mapswithme/maps/settings/StoragePathManager.java index 28dce61b89..03ebe99643 100644 --- a/android/src/com/mapswithme/maps/settings/StoragePathManager.java +++ b/android/src/com/mapswithme/maps/settings/StoragePathManager.java @@ -131,11 +131,6 @@ public class StoragePathManager } } - boolean hasMoreThanOneStorage() - { - return mItems.size() > 1; - } - List getStorageItems() { return mItems; @@ -228,13 +223,6 @@ public class StoragePathManager continue; } - final long freeSize = StorageUtils.getFreeBytesAtPath(path); - if (freeSize <= 0) - { - LOGGER.i(TAG, "Rejected " + path + ": not enough space"); - continue; - } - if (!dir.canWrite() || !StorageUtils.isDirWritable(path)) { LOGGER.i(TAG, "Rejected " + path + ": not writable"); @@ -247,6 +235,7 @@ public class StoragePathManager continue; } + final long freeSize = StorageUtils.getFreeBytesAtPath(path); StorageItem item = new StorageItem(path, freeSize); if (!TextUtils.isEmpty(configDir) && configDir.equals(path)) { -- 2.45.3 From 2fc0453127f992f9afa2490c151cad7d56207367 Mon Sep 17 00:00:00 2001 From: Konstantin Pastbin Date: Sun, 24 Apr 2022 08:35:42 +0300 Subject: [PATCH 8/9] [android] Remove extra mkdir() writability test needed for KitKat Signed-off-by: Konstantin Pastbin --- .../maps/settings/StoragePathManager.java | 5 ++--- .../src/com/mapswithme/util/StorageUtils.java | 20 ------------------- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/android/src/com/mapswithme/maps/settings/StoragePathManager.java b/android/src/com/mapswithme/maps/settings/StoragePathManager.java index 03ebe99643..84e71458e5 100644 --- a/android/src/com/mapswithme/maps/settings/StoragePathManager.java +++ b/android/src/com/mapswithme/maps/settings/StoragePathManager.java @@ -222,8 +222,7 @@ public class StoragePathManager LOGGER.i(TAG, "Rejected " + path + ": not a directory"); continue; } - - if (!dir.canWrite() || !StorageUtils.isDirWritable(path)) + if (!dir.canWrite()) { LOGGER.i(TAG, "Rejected " + path + ": not writable"); continue; @@ -443,7 +442,7 @@ public class StoragePathManager throw new IllegalStateException("Cannot move maps. New path is not a directory. New path : " + newDir); if (!oldDir.isDirectory()) throw new IllegalStateException("Cannot move maps. Old path is not a directory. Old path : " + oldDir); - if (!StorageUtils.isDirWritable(fullNewPath)) + if (!newDir.canWrite()) throw new IllegalStateException("Cannot move maps. New path is not writable. New path : " + fullNewPath); } diff --git a/android/src/com/mapswithme/util/StorageUtils.java b/android/src/com/mapswithme/util/StorageUtils.java index 888c3e75b0..3441c760d7 100644 --- a/android/src/com/mapswithme/util/StorageUtils.java +++ b/android/src/com/mapswithme/util/StorageUtils.java @@ -250,26 +250,6 @@ public class StorageUtils } } - /** - * Check if directory is writable. On some devices with KitKat (eg, Samsung S4) simple File.canWrite() returns - * true for some actually read only directories on sdcard. - * see https://code.google.com/p/android/issues/detail?id=66369 for details - * - * @param path path to ckeck - * @return result - */ - @SuppressWarnings("ResultOfMethodCallIgnored") - public static boolean isDirWritable(String path) - { - File f = new File(path, "mapsme_test_dir"); - f.mkdir(); - if (!f.exists()) - return false; - - f.delete(); - return true; - } - public static long getFreeBytesAtPath(String path) { long size = 0; -- 2.45.3 From 8272a0a9497aece5fccdae0ecf9f4dd04c1f1bec Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Tue, 26 Apr 2022 23:40:15 +0300 Subject: [PATCH 9/9] [routing] Fixed surface factors to fit constraint tertiary+gravel is better than track. Signed-off-by: Viktor Govako --- generator/generator_tests/osm_type_test.cpp | 8 + .../routing_integration_tests/route_test.cpp | 13 ++ routing_common/car_model.cpp | 10 +- routing_common/car_model_coefs.hpp | 1 + .../vehicle_model_test.cpp | 203 ++++++++++-------- routing_common/vehicle_model.hpp | 19 +- 6 files changed, 144 insertions(+), 110 deletions(-) diff --git a/generator/generator_tests/osm_type_test.cpp b/generator/generator_tests/osm_type_test.cpp index 202e516aa0..bdb8b6a775 100644 --- a/generator/generator_tests/osm_type_test.cpp +++ b/generator/generator_tests/osm_type_test.cpp @@ -555,8 +555,16 @@ UNIT_CLASS_TEST(TestWithClassificator, OsmType_Surface) TestSurfaceTypes("asphalt", "bad", "", "paved_bad"); TestSurfaceTypes("asphalt", "", "0", "paved_bad"); + TestSurfaceTypes("fine_gravel", "", "", "paved_bad"); TestSurfaceTypes("fine_gravel", "intermediate", "", "paved_bad"); + + // We definitely should store more than 4 surface options. + // Gravel (widely used tag) always goes to unpaved_bad which is strange sometimes. + // At the same time, we can't definitely say that it's unpaved_good :) + TestSurfaceTypes("gravel", "excellent", "", "unpaved_good"); + TestSurfaceTypes("gravel", "", "", "unpaved_bad"); TestSurfaceTypes("gravel", "intermediate", "", "unpaved_bad"); + TestSurfaceTypes("paved", "intermediate", "", "paved_good"); TestSurfaceTypes("", "intermediate", "", "unpaved_good"); diff --git a/routing/routing_integration_tests/route_test.cpp b/routing/routing_integration_tests/route_test.cpp index 1041399b49..568714de49 100644 --- a/routing/routing_integration_tests/route_test.cpp +++ b/routing/routing_integration_tests/route_test.cpp @@ -662,4 +662,17 @@ using namespace std; mercator::FromLatLon(34.7068976, 33.1199084), {0., 0.}, mercator::FromLatLon(34.7070505, 33.1198391), 670.077); } + + UNIT_TEST(Crimea_UseGravelTertiary) + { + integration::CalculateRouteAndTestRouteLength( + integration::GetVehicleComponents(VehicleType::Car), + mercator::FromLatLon(45.362591, 36.471533), {0., 0.}, + mercator::FromLatLon(45.475055, 36.341766), 18815.6); + + integration::CalculateRouteAndTestRouteLength( + integration::GetVehicleComponents(VehicleType::Car), + mercator::FromLatLon(45.470764, 36.331289), {0., 0.}, + mercator::FromLatLon(45.424964, 36.080336), 55220.2); + } } // namespace route_test diff --git a/routing_common/car_model.cpp b/routing_common/car_model.cpp index 049450c194..c8d95a2fd3 100644 --- a/routing_common/car_model.cpp +++ b/routing_common/car_model.cpp @@ -46,12 +46,6 @@ VehicleModel::LimitsInitList const kCarOptionsDefault = { {{"highway", "living_street"}, true}, {{"highway", "road"}, true}, {{"highway", "track"}, true} - /// @todo: Add to classificator - //{ {"highway", "shuttle_train"}, 10 }, - //{ {"highway", "ferry"}, 5 }, - //{ {"highway", "default"}, 10 }, - /// @todo: Check type - //{ {"highway", "construction"}, 40 }, }; VehicleModel::LimitsInitList const kCarOptionsNoPassThroughLivingStreet = { @@ -134,12 +128,14 @@ VehicleModel::AdditionalRoadsList const kAdditionalRoads = { {{"route", "ferry"}, kHighwayBasedSpeeds.Get(HighwayType::RouteFerry)}, {{"man_made", "pier"}, kHighwayBasedSpeeds.Get(HighwayType::ManMadePier)}}; +/// @todo Should make some compare constrains (like in CarModel_TrackVsGravelTertiary test) +/// to better fit these factors with reality. I have no idea, how they were set. VehicleModel::SurfaceInitList const kCarSurface = { // {{surfaceType, surfaceType}, {weightFactor, etaFactor}} {{"psurface", "paved_good"}, {1.0, 1.0}}, {{"psurface", "paved_bad"}, {0.5, 0.5}}, {{"psurface", "unpaved_good"}, {0.4, 0.8}}, - {{"psurface", "unpaved_bad"}, {0.1, 0.3}} + {{"psurface", "unpaved_bad"}, {0.2, 0.3}} }; // Names must be the same with country names from countries.txt diff --git a/routing_common/car_model_coefs.hpp b/routing_common/car_model_coefs.hpp index 8562232246..bb6468d18f 100644 --- a/routing_common/car_model_coefs.hpp +++ b/routing_common/car_model_coefs.hpp @@ -48,6 +48,7 @@ HighwayBasedSpeeds const kHighwayBasedSpeeds = { {HighwayType::HighwaySecondary, InOutCitySpeedKMpH(60.00 /* in city */, 70.00 /* out city */)}, {HighwayType::HighwaySecondaryLink, InOutCitySpeedKMpH(48.00 /* in city */, 56.00 /* out city */)}, {HighwayType::HighwayService, InOutCitySpeedKMpH({15.00, 15.00} /* in city */, {15.00, 15.00} /* out city */)}, + /// @todo Why tertiary is the only road with inCity speed _bigger_ than outCity? {HighwayType::HighwayTertiary, InOutCitySpeedKMpH(60.00 /* in city */, 50.00 /* out city */)}, {HighwayType::HighwayTertiaryLink, InOutCitySpeedKMpH({40.95, 34.97} /* in city */, {45.45, 39.73} /* out city */)}, {HighwayType::HighwayTrack, InOutCitySpeedKMpH({5.00, 5.00} /* in city */, {5.00, 5.00} /* out city */)}, diff --git a/routing_common/routing_common_tests/vehicle_model_test.cpp b/routing_common/routing_common_tests/vehicle_model_test.cpp index b5f419dacd..f0feac3483 100644 --- a/routing_common/routing_common_tests/vehicle_model_test.cpp +++ b/routing_common/routing_common_tests/vehicle_model_test.cpp @@ -3,19 +3,16 @@ #include "routing_common/car_model_coefs.hpp" #include "routing_common/maxspeed_conversion.hpp" #include "routing_common/vehicle_model.hpp" +#include "routing_common/car_model.hpp" #include "indexer/classificator.hpp" #include "indexer/classificator_loader.hpp" -#include "indexer/feature.hpp" +#include "indexer/feature_data.hpp" #include "platform/measurement_utils.hpp" -#include "base/macros.hpp" #include "base/math.hpp" -#include -#include - namespace vehicle_model_test { using namespace routing; @@ -54,52 +51,53 @@ VehicleModel::SurfaceInitList const kCarSurface = { class VehicleModelTest { public: - VehicleModelTest() { classificator::Load(); } + VehicleModelTest() + { + classificator::Load(); + auto const & c = classif(); + + primary = c.GetTypeByPath({"highway", "primary"}); + secondary = c.GetTypeByPath({"highway", "secondary"}); + secondaryBridge = c.GetTypeByPath({"highway", "secondary", "bridge"}); + secondaryTunnel = c.GetTypeByPath({"highway", "secondary", "tunnel"}); + residential = c.GetTypeByPath({"highway", "residential"}); + + oneway = c.GetTypeByPath({"hwtag", "oneway"}); + pavedGood = c.GetTypeByPath({"psurface", "paved_good"}); + pavedBad = c.GetTypeByPath({"psurface", "paved_bad"}); + unpavedGood = c.GetTypeByPath({"psurface", "unpaved_good"}); + unpavedBad = c.GetTypeByPath({"psurface", "unpaved_bad"}); + } + + uint32_t primary, secondary, secondaryTunnel, secondaryBridge, residential; + uint32_t oneway, pavedGood, pavedBad, unpavedGood, unpavedBad; }; -class TestVehicleModel : public VehicleModel +class VehicleModelStub : public VehicleModel { - friend void CheckOneWay(initializer_list const & types, bool expectedValue); - friend void CheckPassThroughAllowed(initializer_list const & types, bool expectedValue); - friend void CheckSpeedWithParams(initializer_list const & types, - SpeedParams const & params, SpeedKMpH const & expectedSpeed); - public: - TestVehicleModel() + VehicleModelStub() : VehicleModel(classif(), kTestLimits, kCarSurface, {kDefaultSpeeds, kDefaultFactors}) { } // We are not going to use offroad routing in these tests. - SpeedKMpH const & GetOffroadSpeed() const override { return kDummy; } - -private: - static SpeedKMpH const kDummy; + SpeedKMpH const & GetOffroadSpeed() const override + { + static SpeedKMpH offroad{0.0 /* weight */, 0.0 /* eta */}; + return offroad; + } }; -SpeedKMpH const TestVehicleModel::kDummy = {0.0 /* weight */, 0.0 /* eta */}; - -uint32_t GetType(char const * s0, char const * s1 = 0, char const * s2 = 0) -{ - char const * const t[] = {s0, s1, s2}; - size_t const size = (s0 != 0) + size_t(s1 != 0) + size_t(s2 != 0); - return classif().GetTypeByPath(vector(t, t + size)); -} - -uint32_t GetOnewayType() -{ - return GetType("hwtag", "oneway"); -} - void CheckSpeedWithParams(initializer_list const & types, SpeedParams const & params, SpeedKMpH const & expectedSpeed) { - TestVehicleModel vehicleModel; + VehicleModelStub model; feature::TypesHolder h; for (uint32_t t : types) h.Add(t); - TEST_EQUAL(vehicleModel.GetTypeSpeed(h, params), expectedSpeed, ()); + TEST_EQUAL(model.GetTypeSpeed(h, params), expectedSpeed, ()); } void CheckSpeed(initializer_list const & types, InOutCitySpeedKMpH const & expectedSpeed) @@ -112,98 +110,81 @@ void CheckSpeed(initializer_list const & types, InOutCitySpeedKMpH con void CheckOneWay(initializer_list const & types, bool expectedValue) { - TestVehicleModel vehicleModel; + VehicleModelStub model; feature::TypesHolder h; for (uint32_t t : types) h.Add(t); - TEST_EQUAL(vehicleModel.HasOneWayType(h), expectedValue, ()); + TEST_EQUAL(model.HasOneWayType(h), expectedValue, ()); } void CheckPassThroughAllowed(initializer_list const & types, bool expectedValue) { - TestVehicleModel vehicleModel; + VehicleModelStub model; feature::TypesHolder h; for (uint32_t t : types) h.Add(t); - TEST_EQUAL(vehicleModel.HasPassThroughType(h), expectedValue, ()); + TEST_EQUAL(model.HasPassThroughType(h), expectedValue, ()); } -UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxSpeed) +UNIT_CLASS_TEST(VehicleModelStub, MaxSpeed) { - TestVehicleModel vehicleModel; - TEST_EQUAL(vehicleModel.GetMaxWeightSpeed(), 150.0, ()); + TEST_EQUAL(GetMaxWeightSpeed(), 150.0, ()); } -UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed) +UNIT_CLASS_TEST(VehicleModelTest, Speed) { { - CheckSpeed({GetType("highway", "secondary", "bridge")}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); - CheckSpeed({GetType("highway", "secondary", "tunnel")}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); - CheckSpeed({GetType("highway", "secondary")}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); + CheckSpeed({secondaryBridge}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); + CheckSpeed({secondaryTunnel}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); + CheckSpeed({secondary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); } - CheckSpeed({GetType("highway", "trunk")}, + CheckSpeed({classif().GetTypeByPath({"highway", "trunk"})}, {SpeedKMpH(100.0 /* weight */, 100.0 /* eta */) /* in city */, SpeedKMpH(150.0 /* weight */, 150.0 /* eta */) /* out of city */}); - CheckSpeed({GetType("highway", "primary")}, {SpeedKMpH(90.0, 90.0), SpeedKMpH(120.0, 120.0)}); - CheckSpeed({GetType("highway", "residential")}, {SpeedKMpH(22.5, 27.5), SpeedKMpH(25.0, 30.0)}); + CheckSpeed({primary}, {SpeedKMpH(90.0, 90.0), SpeedKMpH(120.0, 120.0)}); + CheckSpeed({residential}, {SpeedKMpH(22.5, 27.5), SpeedKMpH(25.0, 30.0)}); } -UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed_MultiTypes) +UNIT_CLASS_TEST(VehicleModelTest, Speed_MultiTypes) { - uint32_t const typeTunnel = GetType("highway", "secondary", "tunnel"); - uint32_t const typeSecondary = GetType("highway", "secondary"); - uint32_t const typeHighway = GetType("highway"); + uint32_t const typeHighway = classif().GetTypeByPath({"highway"}); - CheckSpeed({typeTunnel, typeSecondary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); - CheckSpeed({typeTunnel, typeHighway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); - CheckSpeed({typeHighway, typeTunnel}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); + CheckSpeed({secondaryTunnel, secondary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); + CheckSpeed({secondaryTunnel, typeHighway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); + CheckSpeed({typeHighway, secondaryTunnel}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); } -UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_OneWay) +UNIT_CLASS_TEST(VehicleModelTest, OneWay) { - uint32_t const typeBridge = GetType("highway", "secondary", "bridge"); - uint32_t const typeOneway = GetOnewayType(); + CheckSpeed({secondaryBridge, oneway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); + CheckOneWay({secondaryBridge, oneway}, true); + CheckSpeed({oneway, secondaryBridge}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); + CheckOneWay({oneway, secondaryBridge}, true); - CheckSpeed({typeBridge, typeOneway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); - CheckOneWay({typeBridge, typeOneway}, true); - CheckSpeed({typeOneway, typeBridge}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); - CheckOneWay({typeOneway, typeBridge}, true); - - CheckOneWay({typeOneway}, true); + CheckOneWay({oneway}, true); } -UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_DifferentSpeeds) +UNIT_CLASS_TEST(VehicleModelTest, DifferentSpeeds) { - uint32_t const typeSecondary = GetType("highway", "secondary"); - uint32_t const typePrimary = GetType("highway", "primary"); - uint32_t const typeOneway = GetOnewayType(); - - CheckSpeed({typeSecondary, typePrimary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); - - CheckSpeed({typeSecondary, typePrimary, typeOneway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); - CheckOneWay({typePrimary, typeOneway, typeSecondary}, true); + // What is the purpose of this artificial test with several highway types? To show that order is important? + CheckSpeed({secondary, primary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary)); + CheckSpeed({oneway, primary, secondary}, kDefaultSpeeds.Get(HighwayType::HighwayPrimary)); + CheckOneWay({primary, oneway, secondary}, true); } -UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_PassThroughAllowed) +UNIT_CLASS_TEST(VehicleModelTest, PassThroughAllowed) { - CheckPassThroughAllowed({GetType("highway", "secondary")}, true); - CheckPassThroughAllowed({GetType("highway", "primary")}, true); - CheckPassThroughAllowed({GetType("highway", "service")}, false); + CheckPassThroughAllowed({secondary}, true); + CheckPassThroughAllowed({primary}, true); + CheckPassThroughAllowed({classif().GetTypeByPath({"highway", "service"})}, false); } -UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_SpeedFactor) +UNIT_CLASS_TEST(VehicleModelTest, SpeedFactor) { - uint32_t const secondary = GetType("highway", "secondary"); - uint32_t const residential = GetType("highway", "residential"); - uint32_t const pavedGood = GetType("psurface", "paved_good"); - uint32_t const pavedBad = GetType("psurface", "paved_bad"); - uint32_t const unpavedGood = GetType("psurface", "unpaved_good"); - uint32_t const unpavedBad = GetType("psurface", "unpaved_bad"); - CheckSpeed({secondary, pavedGood}, {SpeedKMpH(64.0 /* weight */, 63.0 /* eta */) /* in city */, SpeedKMpH(64.0 /* weight */, 63.0 /* eta */) /* out of city */}); @@ -217,14 +198,8 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_SpeedFactor) CheckSpeed({residential, unpavedBad}, {SpeedKMpH(4.5, 5.5), SpeedKMpH(5.0, 6.0)}); } -UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxspeedFactor) +UNIT_CLASS_TEST(VehicleModelTest, MaxspeedFactor) { - uint32_t const secondary = GetType("highway", "secondary"); - uint32_t const residential = GetType("highway", "residential"); - uint32_t const primary = GetType("highway", "primary"); - uint32_t const pavedGood = GetType("psurface", "paved_good"); - uint32_t const unpavedBad = GetType("psurface", "unpaved_bad"); - Maxspeed const maxspeed90 = Maxspeed(measurement_utils::Units::Metric, 90 /* forward speed */, kInvalidSpeed); CheckSpeedWithParams({secondary, unpavedBad}, @@ -251,6 +226,46 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxspeedFactor) SpeedKMpH(24.0, 27.0)); } +namespace +{ +bool LessSpeed(SpeedKMpH const & l, SpeedKMpH const & r) +{ + TEST(l.IsValid() && r.IsValid(), (l, r)); + return l.m_weight < r.m_weight && l.m_eta < r.m_eta; +} + +#define TEST_LESS_SPEED(l, r) TEST(LessSpeed(l, r), (l, r)) +} // namespace + +UNIT_CLASS_TEST(VehicleModelTest, CarModel_TrackVsGravelTertiary) +{ + auto const & model = CarModel::AllLimitsInstance(); + + auto const & c = classif(); + feature::TypesHolder h1; + h1.Add(c.GetTypeByPath({"highway", "track"})); + + feature::TypesHolder h2; + h2.Add(c.GetTypeByPath({"highway", "tertiary"})); + h2.Add(unpavedBad); // from OSM surface=gravel + + // https://www.openstreetmap.org/#map=19/45.43640/36.39689 + // Obvious that gravel tertiary (moreover with maxspeed=60kmh) should be better than track. + + { + SpeedParams p1({}, kInvalidSpeed, false /* inCity */); + SpeedParams p2({measurement_utils::Units::Metric, 60, 60}, kInvalidSpeed, false /* inCity */); + TEST_LESS_SPEED(model.GetTypeSpeed(h1, p1), model.GetTypeSpeed(h2, p2)); + } + + { + SpeedParams p({}, kInvalidSpeed, false /* inCity */); + TEST_LESS_SPEED(model.GetTypeSpeed(h1, p), model.GetTypeSpeed(h2, p)); + } +} + +#undef TEST_LESS_SPEED + UNIT_TEST(VehicleModel_MultiplicationOperatorTest) { SpeedKMpH const speed(90 /* weight */, 100 /* eta */); @@ -258,13 +273,13 @@ UNIT_TEST(VehicleModel_MultiplicationOperatorTest) SpeedKMpH const lResult = speed * factor; SpeedKMpH const rResult = factor * speed; TEST_EQUAL(lResult, rResult, ()); - TEST(base::AlmostEqualAbs(lResult.m_weight, 90.0, 1e-7), ()); - TEST(base::AlmostEqualAbs(lResult.m_eta, 110.0, 1e-7), ()); + TEST(base::AlmostEqualULPs(lResult.m_weight, 90.0), ()); + TEST(base::AlmostEqualULPs(lResult.m_eta, 110.0), ()); } UNIT_TEST(VehicleModel_CarModelValidation) { - vector const carRoadTypes = { + HighwayType const carRoadTypes[] = { HighwayType::HighwayLivingStreet, HighwayType::HighwayMotorway, HighwayType::HighwayMotorwayLink, HighwayType::HighwayPrimary, HighwayType::HighwayPrimaryLink, HighwayType::HighwayResidential, diff --git a/routing_common/vehicle_model.hpp b/routing_common/vehicle_model.hpp index 3db98867a8..6c067d78ba 100644 --- a/routing_common/vehicle_model.hpp +++ b/routing_common/vehicle_model.hpp @@ -68,7 +68,7 @@ using HighwayBasedSpeeds = base::SmallMap; /// \brief Params for calculation of an approximate speed on a feature. struct SpeedParams { - /// For unit tests compatibility. + /// @deprecated For unit tests compatibility. SpeedParams(bool forward, bool inCity, Maxspeed const & maxspeed) : m_maxspeed(maxspeed), m_defSpeedKmPH(kInvalidSpeed), m_inCity(inCity), m_forward(forward) { @@ -291,6 +291,7 @@ public: bool IsPassThroughAllowed(FeatureType & f) const override; /// @} + // Made public to have simple access from unit tests. public: /// @returns true if |m_highwayTypes| or |m_addRoadTypes| contains |type| and false otherwise. bool IsRoadType(uint32_t type) const; @@ -314,14 +315,6 @@ public: (m_onewayType == rhs.m_onewayType); } -protected: - /// @returns a special restriction which is set to the feature. - virtual RoadAvailability GetRoadAvailability(feature::TypesHolder const & types) const; - - void AddAdditionalRoadTypes(Classificator const & classif, AdditionalRoadsList const & roads); - - uint32_t PrepareToMatchType(uint32_t type) const; - /// \returns true if |types| is a oneway feature. /// \note According to OSM, tag "oneway" could have value "-1". That means it's a oneway feature /// with reversed geometry. In that case at map generation the geometry of such features @@ -331,6 +324,14 @@ protected: bool HasPassThroughType(feature::TypesHolder const & types) const; +protected: + /// @returns a special restriction which is set to the feature. + virtual RoadAvailability GetRoadAvailability(feature::TypesHolder const & types) const; + + void AddAdditionalRoadTypes(Classificator const & classif, AdditionalRoadsList const & roads); + + uint32_t PrepareToMatchType(uint32_t type) const; + SpeedKMpH GetSpeedWihtoutMaxspeed(FeatureType & f, SpeedParams params) const; /// \brief Maximum within all the speed limits set in a model (car model, bicycle model and so on). -- 2.45.3