From d903219a8a98fc7b68a87215efa7e8a08e70e563 Mon Sep 17 00:00:00 2001 From: Maksim Andrianov Date: Tue, 8 Dec 2020 14:26:07 +0300 Subject: [PATCH 01/39] [generator] Added call Clear(). --- generator/osm_source.cpp | 8 ++++++-- generator/raw_generator.cpp | 7 +++++-- generator/translators_pool.cpp | 2 +- generator/translators_pool.hpp | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/generator/osm_source.cpp b/generator/osm_source.cpp index 6a76031595..ab35f0f7e6 100644 --- a/generator/osm_source.cpp +++ b/generator/osm_source.cpp @@ -123,7 +123,10 @@ void ProcessOsmElementsFromXML(SourceReader & stream, function(m_chunkSize); + translators.Emit(elements); + + for (auto & e : elements) + e.Clear(); + element_pos = 0; } elements.resize(element_pos); diff --git a/generator/translators_pool.cpp b/generator/translators_pool.cpp index 137e4381db..fa9ec7b195 100644 --- a/generator/translators_pool.cpp +++ b/generator/translators_pool.cpp @@ -15,7 +15,7 @@ TranslatorsPool::TranslatorsPool(std::shared_ptr const & or m_translators.Push(original->Clone()); } -void TranslatorsPool::Emit(std::vector && elements) +void TranslatorsPool::Emit(std::vector elements) { std::shared_ptr translator; m_translators.WaitAndPop(translator); diff --git a/generator/translators_pool.hpp b/generator/translators_pool.hpp index f2e973cd24..d2c4c73f2c 100644 --- a/generator/translators_pool.hpp +++ b/generator/translators_pool.hpp @@ -18,7 +18,7 @@ public: explicit TranslatorsPool(std::shared_ptr const & original, size_t threadCount); - void Emit(std::vector && elements); + void Emit(std::vector elements); bool Finish(); private: From 0c291281c4def37528b87b14123a177ce17a1c5e Mon Sep 17 00:00:00 2001 From: Maksim Andrianov Date: Tue, 8 Dec 2020 13:10:19 +0300 Subject: [PATCH 02/39] [generator] Added log messages. --- generator/osm_source.cpp | 4 ++- generator/osm_source.hpp | 2 ++ generator/raw_generator.cpp | 66 +++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/generator/osm_source.cpp b/generator/osm_source.cpp index ab35f0f7e6..a7298798d2 100644 --- a/generator/osm_source.cpp +++ b/generator/osm_source.cpp @@ -47,7 +47,9 @@ SourceReader::SourceReader(istringstream & stream) uint64_t SourceReader::Read(char * buffer, uint64_t bufferSize) { m_file->read(buffer, bufferSize); - return m_file->gcount(); + auto const gcount = static_cast(m_file->gcount()); + m_pos += gcount; + return gcount; } // Functions --------------------------------------------------------------------------------------- diff --git a/generator/osm_source.hpp b/generator/osm_source.hpp index 51cc128a2b..40ca97b6be 100644 --- a/generator/osm_source.hpp +++ b/generator/osm_source.hpp @@ -34,6 +34,7 @@ class SourceReader }; std::unique_ptr m_file; + uint64_t m_pos = 0; public: SourceReader(); @@ -41,6 +42,7 @@ public: explicit SourceReader(std::istringstream & stream); uint64_t Read(char * buffer, uint64_t bufferSize); + uint64_t Pos() const { return m_pos; } }; bool GenerateIntermediateData(feature::GenerateInfo & info); diff --git a/generator/raw_generator.cpp b/generator/raw_generator.cpp index 3da779ddc5..a57bfa144c 100644 --- a/generator/raw_generator.cpp +++ b/generator/raw_generator.cpp @@ -12,11 +12,73 @@ #include "generator/translators_pool.hpp" #include "base/thread_pool_computational.hpp" +#include "base/timer.hpp" #include "defines.hpp" namespace generator { +namespace +{ +class Stats +{ +public: + Stats(size_t logCallCountThreshold) + : m_timer(true /* start */), m_logCallCountThreshold(logCallCountThreshold) + { + } + + void Log(std::vector const & elements, uint64_t pos, bool forcePrint = false) + { + for (auto const & e : elements) + { + if (e.IsNode()) + ++m_node_counter; + else if (e.IsWay()) + ++m_way_counter; + else if (e.IsRelation()) + ++m_relation_counter; + } + + m_element_counter += elements.size(); + if (!forcePrint && m_callCount != m_logCallCountThreshold) + { + m_callCount++; + return; + } + + auto static constexpr kBInMB = 1024.0 * 1024.0; + auto const posMB = pos / kBInMB; + auto const elapsedSeconds = m_timer.ElapsedSeconds(); + auto const avgSpeedMBPerSec = posMB / elapsedSeconds; + auto const speedMBPerSec = + (pos - m_prevFilePos) / (elapsedSeconds - m_prevElapsedSeconds) / kBInMB; + + LOG(LINFO, ("Readed", m_element_counter, "elements [pos:", posMB, "MB, avg r:", + avgSpeedMBPerSec, " MB/s, r:", speedMBPerSec, "MB/s [n:", m_node_counter, + ", w:", m_way_counter, ", r:", m_relation_counter, "]]")); + + m_prevFilePos = pos; + m_prevElapsedSeconds = elapsedSeconds; + m_node_counter = 0; + m_way_counter = 0; + m_relation_counter = 0; + m_callCount = 0; + } + +private: + const size_t m_logCallCountThreshold = 0; + base::Timer m_timer; + size_t m_callCount = 0; + uint64_t m_prevFilePos = 0; + double m_prevElapsedSeconds = 0.0; + size_t m_element_counter = 0; + size_t m_node_counter = 0; + size_t m_way_counter = 0; + size_t m_relation_counter = 0; +}; +} // namespace + RawGenerator::RawGenerator(feature::GenerateInfo & genInfo, size_t threadsCount, size_t chunkSize) : m_genInfo(genInfo) , m_threadsCount(threadsCount) @@ -176,6 +238,8 @@ bool RawGenerator::GenerateFilteredFeatures() RawGeneratorWriter rawGeneratorWriter(m_queue, m_genInfo.m_tmpDir); rawGeneratorWriter.Run(); + Stats stats(100 * m_threadsCount /* logCallCountThreshold */); + size_t element_pos = 0; std::vector elements(m_chunkSize); while (sourceProcessor->TryRead(elements[element_pos])) @@ -183,6 +247,7 @@ bool RawGenerator::GenerateFilteredFeatures() if (++element_pos != m_chunkSize) continue; + stats.Log(elements, reader.Pos()); translators.Emit(elements); for (auto & e : elements) @@ -191,6 +256,7 @@ bool RawGenerator::GenerateFilteredFeatures() element_pos = 0; } elements.resize(element_pos); + stats.Log(elements, reader.Pos(), true /* forcePrint */); translators.Emit(std::move(elements)); LOG(LINFO, ("Input was processed.")); From e8a5bdfbf955da47e1ca8d74acbf6ee8c055feac Mon Sep 17 00:00:00 2001 From: Maksim Andrianov Date: Mon, 25 Jan 2021 16:16:58 +0300 Subject: [PATCH 03/39] Review fixes --- generator/raw_generator.cpp | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/generator/raw_generator.cpp b/generator/raw_generator.cpp index a57bfa144c..d503d3ece1 100644 --- a/generator/raw_generator.cpp +++ b/generator/raw_generator.cpp @@ -33,49 +33,49 @@ public: for (auto const & e : elements) { if (e.IsNode()) - ++m_node_counter; + ++m_nodeCounter; else if (e.IsWay()) - ++m_way_counter; + ++m_wayCounter; else if (e.IsRelation()) - ++m_relation_counter; + ++m_relationCounter; } m_element_counter += elements.size(); if (!forcePrint && m_callCount != m_logCallCountThreshold) { - m_callCount++; + ++m_callCount; return; } - auto static constexpr kBInMB = 1024.0 * 1024.0; - auto const posMB = pos / kBInMB; + auto static constexpr kBytesInMiB = 1024.0 * 1024.0; + auto const posMiB = pos / kBytesInMiB; auto const elapsedSeconds = m_timer.ElapsedSeconds(); - auto const avgSpeedMBPerSec = posMB / elapsedSeconds; - auto const speedMBPerSec = - (pos - m_prevFilePos) / (elapsedSeconds - m_prevElapsedSeconds) / kBInMB; + auto const avgSpeedMiBPerSec = posMiB / elapsedSeconds; + auto const speedMiBPerSec = + (pos - m_prevFilePos) / (elapsedSeconds - m_prevElapsedSeconds) / kBytesInMiB; - LOG(LINFO, ("Readed", m_element_counter, "elements [pos:", posMB, "MB, avg r:", - avgSpeedMBPerSec, " MB/s, r:", speedMBPerSec, "MB/s [n:", m_node_counter, - ", w:", m_way_counter, ", r:", m_relation_counter, "]]")); + LOG(LINFO, ("Read", m_element_counter, "elements [pos:", posMiB, + "MiB, avg read speed:", avgSpeedMiBPerSec, " MiB/s, read speed:", speedMiBPerSec, + "MiB/s [n:", m_nodeCounter, ", w:", m_wayCounter, ", r:", m_relationCounter, "]]")); m_prevFilePos = pos; m_prevElapsedSeconds = elapsedSeconds; - m_node_counter = 0; - m_way_counter = 0; - m_relation_counter = 0; + m_nodeCounter = 0; + m_wayCounter = 0; + m_relationCounter = 0; m_callCount = 0; } private: - const size_t m_logCallCountThreshold = 0; base::Timer m_timer; + size_t const m_logCallCountThreshold = 0; size_t m_callCount = 0; uint64_t m_prevFilePos = 0; double m_prevElapsedSeconds = 0.0; size_t m_element_counter = 0; - size_t m_node_counter = 0; - size_t m_way_counter = 0; - size_t m_relation_counter = 0; + size_t m_nodeCounter = 0; + size_t m_wayCounter = 0; + size_t m_relationCounter = 0; }; } // namespace From 5cbe72368aaf10bcb6b4c4239fc01046ebf7af24 Mon Sep 17 00:00:00 2001 From: Maksim Andrianov Date: Tue, 29 Oct 2019 12:57:03 +0300 Subject: [PATCH 04/39] [generator] Added forgotten ref. --- generator/osm_source.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/osm_source.cpp b/generator/osm_source.cpp index a7298798d2..9e16df4aa6 100644 --- a/generator/osm_source.cpp +++ b/generator/osm_source.cpp @@ -185,7 +185,7 @@ bool ProcessorOsmElementsFromO5M::TryRead(OsmElement & element) // iterating in loop. Furthermore, into Tags() method calls Nodes.Skip() and Members.Skip(), // thus first call of Nodes (Members) after Tags() will not return any results. // So don not reorder the "for" loops (!). - auto const entity = *m_pos; + auto const & entity = *m_pos; element.m_id = entity.id; switch (entity.type) { From 5ed308ed0ed0002e18163ff5b351daad15dbd73a Mon Sep 17 00:00:00 2001 From: Maksim Andrianov Date: Tue, 29 Oct 2019 13:59:11 +0300 Subject: [PATCH 05/39] [generator] Used trim without locale instead of boost::trim. --- generator/osm_element.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/generator/osm_element.cpp b/generator/osm_element.cpp index 2446f6c3ed..6ccc9e24eb 100644 --- a/generator/osm_element.cpp +++ b/generator/osm_element.cpp @@ -9,6 +9,27 @@ #include #include +namespace +{ +std::string & Ltrim(std::string & s) +{ + s.erase(s.begin(), std::find_if(s.cbegin(), s.cend(), [](auto c) {return !std::isspace(c); })); + return s; +} + +std::string & Rtrim(std::string & s) +{ + s.erase(std::find_if(s.crbegin(), s.crend(), [](auto c) {return !std::isspace(c); }).base(), + s.end()); + return s; +} + +std::string & Trim(std::string & s) +{ + return Ltrim(Rtrim(s)); +} +} // namespace + std::string DebugPrint(OsmElement::EntityType type) { switch (type) @@ -69,8 +90,7 @@ void OsmElement::AddTag(char const * key, char const * value) #undef SKIP_KEY_BY_PREFIX std::string val{value}; - strings::Trim(val); - m_tags.emplace_back(key, std::move(val)); + m_tags.emplace_back(key, std::move(Trim(val))); } void OsmElement::AddTag(std::string const & key, std::string const & value) From f4d915c0f288c0663b2ba2d34443b8947e992558 Mon Sep 17 00:00:00 2001 From: Maksim Andrianov Date: Mon, 7 Dec 2020 22:22:00 +0300 Subject: [PATCH 06/39] [base] Trim impl was replaced to faster. --- base/string_utils.cpp | 23 +++++++++++++++++++++-- base/string_utils.hpp | 6 +++--- generator/osm_element.cpp | 25 ++----------------------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/base/string_utils.cpp b/base/string_utils.cpp index 9b9c96a709..3425d4e6a8 100644 --- a/base/string_utils.cpp +++ b/base/string_utils.cpp @@ -203,8 +203,27 @@ char ascii_to_lower(char in) } // namespace void AsciiToLower(std::string & s) { transform(s.begin(), s.end(), s.begin(), &ascii_to_lower); } -void Trim(std::string & s) { boost::trim(s); } -void Trim(std::string & s, char const * anyOf) { boost::trim_if(s, boost::is_any_of(anyOf)); } + +std::string & Ltrim(std::string & s) +{ + s.erase(s.begin(), std::find_if(s.cbegin(), s.cend(), [](auto c) { return !std::isspace(c); })); + return s; +} + +std::string & Rtrim(std::string & s) +{ + s.erase(std::find_if(s.crbegin(), s.crend(), [](auto c) { return !std::isspace(c); }).base(), + s.end()); + return s; +} + +std::string & Trim(std::string & s) { return Ltrim(Rtrim(s)); } + +std::string & Trim(std::string & s, char const * anyOf) +{ + boost::trim_if(s, boost::is_any_of(anyOf)); + return s; +} bool ReplaceFirst(std::string & str, std::string const & from, std::string const & to) { diff --git a/base/string_utils.hpp b/base/string_utils.hpp index c26d6e4105..561ff90cdd 100644 --- a/base/string_utils.hpp +++ b/base/string_utils.hpp @@ -101,11 +101,11 @@ void NormalizeDigits(UniString & us); size_t CountNormLowerSymbols(UniString const & s, UniString const & lowStr); void AsciiToLower(std::string & s); -// TODO(AlexZ): current boost impl uses default std::locale() to trim. +// TODO(AlexZ): current impl works as boost trim, that uses default std::locale() to trim. // In general, it does not work for any unicode whitespace except ASCII U+0020 one. -void Trim(std::string & s); +std::string & Trim(std::string & s); /// Remove any characters that contain in "anyOf" on left and right side of string s -void Trim(std::string & s, char const * anyOf); +std::string & Trim(std::string & s, char const * anyOf); // Replace the first match of the search substring in the input with the format string. // str - An input string diff --git a/generator/osm_element.cpp b/generator/osm_element.cpp index 6ccc9e24eb..e5993f9212 100644 --- a/generator/osm_element.cpp +++ b/generator/osm_element.cpp @@ -9,27 +9,6 @@ #include #include -namespace -{ -std::string & Ltrim(std::string & s) -{ - s.erase(s.begin(), std::find_if(s.cbegin(), s.cend(), [](auto c) {return !std::isspace(c); })); - return s; -} - -std::string & Rtrim(std::string & s) -{ - s.erase(std::find_if(s.crbegin(), s.crend(), [](auto c) {return !std::isspace(c); }).base(), - s.end()); - return s; -} - -std::string & Trim(std::string & s) -{ - return Ltrim(Rtrim(s)); -} -} // namespace - std::string DebugPrint(OsmElement::EntityType type) { switch (type) @@ -89,8 +68,8 @@ void OsmElement::AddTag(char const * key, char const * value) SKIP_KEY_BY_PREFIX("official_name"); #undef SKIP_KEY_BY_PREFIX - std::string val{value}; - m_tags.emplace_back(key, std::move(Trim(val))); + std::string val(value); + m_tags.emplace_back(key, std::move(strings::Trim(val))); } void OsmElement::AddTag(std::string const & key, std::string const & value) From 00749341a3bddb17c620874eb274d26315dd6300 Mon Sep 17 00:00:00 2001 From: Maksim Andrianov Date: Mon, 25 Jan 2021 16:11:24 +0300 Subject: [PATCH 07/39] Review fixes --- base/base_tests/string_utils_test.cpp | 14 ++++++++++++++ base/string_utils.cpp | 6 +++--- base/string_utils.hpp | 8 ++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/base/base_tests/string_utils_test.cpp b/base/base_tests/string_utils_test.cpp index 35c07c5a2a..28ecada741 100644 --- a/base/base_tests/string_utils_test.cpp +++ b/base/base_tests/string_utils_test.cpp @@ -1121,3 +1121,17 @@ UNIT_TEST(Strings_JoinAny) [](auto const & item) { return item.second; }), ()); } } + +UNIT_TEST(Trim) +{ + std::string const kStrWithoutSpaces = "string"; + + std::string strWithLeftSpaces = " " + kStrWithoutSpaces; + TEST_EQUAL(strings::TrimLeft(strWithLeftSpaces), kStrWithoutSpaces, ()); + + std::string strWithRightSpaces = kStrWithoutSpaces + " "; + TEST_EQUAL(strings::TrimRight(strWithRightSpaces), kStrWithoutSpaces, ()); + + std::string strWithLeftRightSpaces = " " + kStrWithoutSpaces + " "; + TEST_EQUAL(strings::Trim(strWithLeftSpaces), kStrWithoutSpaces, ()); +} diff --git a/base/string_utils.cpp b/base/string_utils.cpp index 3425d4e6a8..915e409173 100644 --- a/base/string_utils.cpp +++ b/base/string_utils.cpp @@ -204,20 +204,20 @@ char ascii_to_lower(char in) void AsciiToLower(std::string & s) { transform(s.begin(), s.end(), s.begin(), &ascii_to_lower); } -std::string & Ltrim(std::string & s) +std::string & TrimLeft(std::string & s) { s.erase(s.begin(), std::find_if(s.cbegin(), s.cend(), [](auto c) { return !std::isspace(c); })); return s; } -std::string & Rtrim(std::string & s) +std::string & TrimRight(std::string & s) { s.erase(std::find_if(s.crbegin(), s.crend(), [](auto c) { return !std::isspace(c); }).base(), s.end()); return s; } -std::string & Trim(std::string & s) { return Ltrim(Rtrim(s)); } +std::string & Trim(std::string & s) { return TrimLeft(TrimRight(s)); } std::string & Trim(std::string & s, char const * anyOf) { diff --git a/base/string_utils.hpp b/base/string_utils.hpp index 561ff90cdd..250ab0c7b9 100644 --- a/base/string_utils.hpp +++ b/base/string_utils.hpp @@ -101,8 +101,12 @@ void NormalizeDigits(UniString & us); size_t CountNormLowerSymbols(UniString const & s, UniString const & lowStr); void AsciiToLower(std::string & s); -// TODO(AlexZ): current impl works as boost trim, that uses default std::locale() to trim. -// In general, it does not work for any unicode whitespace except ASCII U+0020 one. + +// All triming functions return a reference on an input string. +// They do in-place trimming. In general, it does not work for any unicode whitespace except +// ASCII U+0020 one. +std::string & TrimLeft(std::string & s); +std::string & TrimRight(std::string & s); std::string & Trim(std::string & s); /// Remove any characters that contain in "anyOf" on left and right side of string s std::string & Trim(std::string & s, char const * anyOf); From 61417b2eff3176d38b6b992bb833dac3ae8f26ca Mon Sep 17 00:00:00 2001 From: velichkomarija Date: Thu, 21 Jan 2021 18:02:34 +0300 Subject: [PATCH 08/39] [android] Fixed night mode in some edittext fields. --- android/res/layout/dialog_edit_text.xml | 15 +- android/res/layout/edit_bookmark_common.xml | 53 +++--- .../res/layout/fragment_edit_description.xml | 6 +- android/res/layout/fragment_editor.xml | 96 ++-------- android/res/layout/fragment_osm_login.xml | 41 ++-- android/res/layout/fragment_ugc_editor.xml | 30 +-- .../res/layout/fragment_ugc_route_edit.xml | 180 +++++++++--------- .../res/layout/item_bookmark_create_group.xml | 14 +- android/res/layout/item_editor_input.xml | 14 +- android/res/layout/item_localized_name.xml | 13 +- 10 files changed, 178 insertions(+), 284 deletions(-) diff --git a/android/res/layout/dialog_edit_text.xml b/android/res/layout/dialog_edit_text.xml index 575e5b32fd..18e59c703d 100644 --- a/android/res/layout/dialog_edit_text.xml +++ b/android/res/layout/dialog_edit_text.xml @@ -5,28 +5,25 @@ android:minWidth="@dimen/width_dialog_base" android:orientation="vertical" android:padding="@dimen/margin_base_plus"> - - + android:textAppearance="@style/MwmTextAppearance.Title" /> - + android:layout_height="wrap_content" + android:textColorHint="?android:textColorSecondary"> - + android:maxLength="100" + android:singleLine="true" /> - diff --git a/android/res/layout/edit_bookmark_common.xml b/android/res/layout/edit_bookmark_common.xml index a05dcb70c4..33219752a7 100644 --- a/android/res/layout/edit_bookmark_common.xml +++ b/android/res/layout/edit_bookmark_common.xml @@ -15,8 +15,10 @@ android:layout_marginRight="@dimen/margin_half" android:orientation="vertical"> + android:layout_height="wrap_content" + android:textColorHint="?android:textColorSecondary"> + android:singleLine="true" /> - - + android:textAppearance="@style/MwmTextAppearance.Body3" /> - + android:paddingBottom="@dimen/margin_half" + android:textAppearance="@style/MwmTextAppearance.Body1" /> - + android:layout_marginBottom="@dimen/margin_half" + android:background="@color/divider" /> + tools:src="@drawable/ic_bookmark_none" /> - - - - + - - - + android:layout_height="wrap_content" + android:hint="@string/edit_description_hint" + android:inputType="textMultiLine" /> + \ No newline at end of file diff --git a/android/res/layout/fragment_edit_description.xml b/android/res/layout/fragment_edit_description.xml index 5264b4bc08..6339f2bba0 100644 --- a/android/res/layout/fragment_edit_description.xml +++ b/android/res/layout/fragment_edit_description.xml @@ -19,9 +19,8 @@ android:gravity="center_vertical" android:padding="@dimen/margin_half" android:text="@string/save" - android:textAppearance="@style/MwmTextAppearance.Toolbar.Title.Button"/> + android:textAppearance="@style/MwmTextAppearance.Toolbar.Title.Button" /> - + android:inputType="textMultiLine" + android:textColorHint="?android:textColorSecondary" /> diff --git a/android/res/layout/fragment_editor.xml b/android/res/layout/fragment_editor.xml index fd75a0617f..1b74eacac2 100644 --- a/android/res/layout/fragment_editor.xml +++ b/android/res/layout/fragment_editor.xml @@ -1,22 +1,20 @@ - - - - - - - - - - - - - - - - - - + android:src="@drawable/ic_address" + tools:ignore="ContentDescription" /> - - + tools:text="Red str." + app:drawableEndCompat="@drawable/ic_arrow_down" /> - - - - - - - - - - - - - - - - - + android:src="@drawable/ic_cuisine" + tools:ignore="ContentDescription" /> - - + tools:text="Italian, russian, russian, russian, russian, russian, russian, russian, russian" + app:drawableEndCompat="@drawable/ic_arrow_down" /> - - - - + android:src="@drawable/ic_wifi" + tools:ignore="ContentDescription" /> - - - - - - - - + android:minHeight="74dp" + android:textColorHint="?android:textColorSecondary"> - - - - - - - - - diff --git a/android/res/layout/fragment_osm_login.xml b/android/res/layout/fragment_osm_login.xml index 320a485fd9..8cf1deacd2 100644 --- a/android/res/layout/fragment_osm_login.xml +++ b/android/res/layout/fragment_osm_login.xml @@ -5,7 +5,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> - - + tools:ignore="UnusedAttribute" /> - - - + android:minHeight="@dimen/height_block_base" + android:textColorHint="?android:textColorSecondary"> - + android:hint="@string/email_or_username" /> - - + android:minHeight="@dimen/height_block_base" + android:textColorHint="?android:textColorSecondary"> - + android:inputType="textPassword" /> - -