diff --git a/CMakeLists.txt b/CMakeLists.txt index de53847..04e8c4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,6 +105,7 @@ add_executable(ARC WIN32 views/log/LogDetailWindow.h database/dao/GeneralLogDAO.cpp database/dao/GeneralLogDAO.h + android/dushanbe/AppVersionTrack.h android/dushanbe/CommonScript.cpp android/dushanbe/CommonScript.h android/dushanbe/GetCardInfoScript.cpp @@ -136,6 +137,7 @@ elseif (APPLE) views/log/LogDetailWindow.h database/dao/GeneralLogDAO.cpp database/dao/GeneralLogDAO.h + android/dushanbe/AppVersionTrack.h android/dushanbe/CommonScript.cpp android/dushanbe/CommonScript.h android/dushanbe/GetCardInfoScript.cpp diff --git a/android/dushanbe/AppVersionTrack.h b/android/dushanbe/AppVersionTrack.h new file mode 100644 index 0000000..7685b11 --- /dev/null +++ b/android/dushanbe/AppVersionTrack.h @@ -0,0 +1,54 @@ +#pragma once + +#include +#include + +namespace Dushanbe { + +// «Трек» формата UI приложения Dushanbe City Bank. Экранные дампы и порядок +// нод в content-desc менялись между версиями приложения; трек — это +// нормализованный ярлык версии, по которому код выбирает версионно-зависимую +// ветку парсинга (см. ScreenXmlParser::setVersionTrack). +// +// На момент введения каркаса форматы 3.2.33 и 3.2.38 практически идентичны, +// поэтому отдельных веток ещё нет — трек служит явным швом для будущих +// расхождений и читаемым маркером в логах/дампах. +enum class AppVersionTrack { + Legacy, // < 3.2.33 — старый blob-формат (один content-desc с "Версия:"/"Сборка:") + V3_2_33, // 3.2.33 .. < 3.2.38 + V3_2_38, // >= 3.2.38 (и новейший по умолчанию) +}; + +// Резолвит трек из строки версии (например "3.2.38", полученной через +// AdbUtils::getAppVersion → BankProfileInfo.appVersion). Сравнение — +// через QVersionNumber, а не лексикографически по строке. +// +// Неизвестная/непарсящаяся версия, а также любая версия новее последнего +// известного порога, трактуется как новейший известный трек (V3_2_38): свежие +// апдейты по умолчанию должны идти по последнему формату, а не падать на Legacy. +inline AppVersionTrack trackForVersion(const QString &appVersion) { + static const QVersionNumber kV3_2_33(3, 2, 33); + static const QVersionNumber kV3_2_38(3, 2, 38); + + qsizetype suffixIndex = 0; + const QVersionNumber v = QVersionNumber::fromString(appVersion.trimmed(), &suffixIndex); + if (v.isNull()) { + // Не смогли распарсить — считаем новейшим известным форматом. + return AppVersionTrack::V3_2_38; + } + if (v < kV3_2_33) return AppVersionTrack::Legacy; + if (v < kV3_2_38) return AppVersionTrack::V3_2_33; + return AppVersionTrack::V3_2_38; +} + +// Человекочитаемое имя трека для логов. +inline const char *trackName(AppVersionTrack track) { + switch (track) { + case AppVersionTrack::Legacy: return "Legacy(<3.2.33)"; + case AppVersionTrack::V3_2_33: return "3.2.33"; + case AppVersionTrack::V3_2_38: return "3.2.38"; + } + return "unknown"; +} + +} // namespace Dushanbe diff --git a/android/dushanbe/GetCardInfoScript.cpp b/android/dushanbe/GetCardInfoScript.cpp index 9df429c..e67667d 100644 --- a/android/dushanbe/GetCardInfoScript.cpp +++ b/android/dushanbe/GetCardInfoScript.cpp @@ -39,6 +39,11 @@ void GetCardInfoScript::doStart() { const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id, app.appVersion}; TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_CARDS", m_deviceId, dumpMeta, &m_error); + // Версионный трек приложения → версионно-зависимый парсинг (см. AppVersionTrack.h). + xmlScreenParser.setVersionTrack(Dushanbe::trackForVersion(app.appVersion)); + qDebug() << "[Dushanbe::GetCardInfo] appVersion=" << app.appVersion + << "→ track" << Dushanbe::trackName(xmlScreenParser.versionTrack()); + xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter)); closeGooglePlayBannerIfVisible(m_deviceId, device.screenWidth, device.screenHeight); diff --git a/android/dushanbe/GetLastTransactionsScript.cpp b/android/dushanbe/GetLastTransactionsScript.cpp index 98a6c79..4c812c4 100644 --- a/android/dushanbe/GetLastTransactionsScript.cpp +++ b/android/dushanbe/GetLastTransactionsScript.cpp @@ -281,6 +281,11 @@ void GetLastTransactionsScript::doStart() { const TaskDumpMeta dumpMeta{m_materialId, firstAmount, {}, {}, app.bankProfileId, app.phone, device.id, app.appVersion}; TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_TRANSACTIONS", m_deviceId, dumpMeta, &m_error); + // Версионный трек приложения → версионно-зависимый парсинг (см. AppVersionTrack.h). + xmlScreenParser.setVersionTrack(Dushanbe::trackForVersion(app.appVersion)); + qDebug() << "[Dushanbe::GetLastTransactions] appVersion=" << app.appVersion + << "→ track" << Dushanbe::trackName(xmlScreenParser.versionTrack()); + xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter)); if (!xmlScreenParser.isHomeScreen()) { diff --git a/android/dushanbe/GetProfileInfoScript.cpp b/android/dushanbe/GetProfileInfoScript.cpp index 80922aa..31a0529 100644 --- a/android/dushanbe/GetProfileInfoScript.cpp +++ b/android/dushanbe/GetProfileInfoScript.cpp @@ -42,6 +42,11 @@ void GetProfileInfoScript::doStart() { const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id, app.appVersion}; TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_PROFILE_INFO", m_deviceId, dumpMeta, &m_error); + // Версионный трек приложения → версионно-зависимый парсинг (см. AppVersionTrack.h). + xmlScreenParser.setVersionTrack(Dushanbe::trackForVersion(app.appVersion)); + qDebug() << "[Dushanbe::GetProfileInfo] appVersion=" << app.appVersion + << "→ track" << Dushanbe::trackName(xmlScreenParser.versionTrack()); + xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter)); if (!xmlScreenParser.isHomeScreen()) { diff --git a/android/dushanbe/LoginAndCheckAccountsScript.cpp b/android/dushanbe/LoginAndCheckAccountsScript.cpp index 24e042f..d10eb3d 100644 --- a/android/dushanbe/LoginAndCheckAccountsScript.cpp +++ b/android/dushanbe/LoginAndCheckAccountsScript.cpp @@ -44,6 +44,11 @@ void LoginAndCheckAccountsScript::doStart() { const TaskDumpMeta dumpMeta{{}, 0, {}, {}, app.bankProfileId, app.phone, device.id, app.appVersion}; TaskDumpRecorder::Scope dumpScope("dushanbe", "FETCH_PROFILE", m_deviceId, dumpMeta, &m_error); + // Версионный трек приложения → версионно-зависимый парсинг (см. AppVersionTrack.h). + xmlScreenParser.setVersionTrack(Dushanbe::trackForVersion(app.appVersion)); + qDebug() << "[Dushanbe::Login] appVersion=" << app.appVersion + << "→ track" << Dushanbe::trackName(xmlScreenParser.versionTrack()); + xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter)); if (!runAppAndGoToHomeScreen(m_deviceId, app.package, app.pinCode, device.screenWidth, device.screenHeight)) { diff --git a/android/dushanbe/PayByCardScript.cpp b/android/dushanbe/PayByCardScript.cpp index 374f906..b9ee45b 100644 --- a/android/dushanbe/PayByCardScript.cpp +++ b/android/dushanbe/PayByCardScript.cpp @@ -126,6 +126,11 @@ void PayByCardScript::doStart() { const TaskDumpMeta dumpMeta{m_account.materialId, m_amount, {}, m_cardNumber, app.bankProfileId, app.phone, device.id, app.appVersion}; TaskDumpRecorder::Scope dumpScope("dushanbe", "CREATE_TRANSACTION_CARD", device.adbSerial, dumpMeta, &m_error); + // Версионный трек приложения → версионно-зависимый парсинг (см. AppVersionTrack.h). + xmlScreenParser.setVersionTrack(Dushanbe::trackForVersion(app.appVersion)); + qDebug() << "[Dushanbe::PayByCard] appVersion=" << app.appVersion + << "→ track" << Dushanbe::trackName(xmlScreenParser.versionTrack()); + xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.adbSerial, ++m_counter)); if (!xmlScreenParser.isHomeScreen()) { diff --git a/android/dushanbe/PayByPhoneScript.cpp b/android/dushanbe/PayByPhoneScript.cpp index 0784345..d2dd257 100644 --- a/android/dushanbe/PayByPhoneScript.cpp +++ b/android/dushanbe/PayByPhoneScript.cpp @@ -123,6 +123,11 @@ void PayByPhoneScript::doStart() { const TaskDumpMeta dumpMeta{m_account.materialId, m_amount, m_phone, {}, app.bankProfileId, app.phone, device.id, app.appVersion}; TaskDumpRecorder::Scope dumpScope("dushanbe", "CREATE_TRANSACTION_PHONE", device.adbSerial, dumpMeta, &m_error); + // Версионный трек приложения → версионно-зависимый парсинг (см. AppVersionTrack.h). + xmlScreenParser.setVersionTrack(Dushanbe::trackForVersion(app.appVersion)); + qDebug() << "[Dushanbe::PayByPhone] appVersion=" << app.appVersion + << "→ track" << Dushanbe::trackName(xmlScreenParser.versionTrack()); + xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.adbSerial, ++m_counter)); if (!xmlScreenParser.isHomeScreen()) { diff --git a/android/dushanbe/ScreenXmlParser.h b/android/dushanbe/ScreenXmlParser.h index 2eea5bd..aeab84e 100644 --- a/android/dushanbe/ScreenXmlParser.h +++ b/android/dushanbe/ScreenXmlParser.h @@ -6,6 +6,7 @@ #include #include #include "android/xml/Node.h" +#include "AppVersionTrack.h" #include "db/MaterialInfo.h" namespace Dushanbe { @@ -20,6 +21,14 @@ public: void parseAndSaveXml(const QString &xml); + // Версионный трек приложения, под которое сейчас идёт парсинг. Скрипт + // выставляет его один раз после загрузки BankProfileInfo: + // parser.setVersionTrack(Dushanbe::trackForVersion(app.appVersion)); + // Версионно-зависимые методы парсинга используют m_track как явный шов + // (см. AppVersionTrack.h). По умолчанию — новейший известный формат. + void setVersionTrack(AppVersionTrack track) { m_track = track; } + AppVersionTrack versionTrack() const { return m_track; } + const QList &findAllNodes() const; Node findTextNode(const QString &text); @@ -173,6 +182,7 @@ public: private: QList m_nodes; QDomElement m_xml; + AppVersionTrack m_track = AppVersionTrack::V3_2_38; }; } // namespace Dushanbe diff --git a/assets/dushanbe/3.2.38/card_transfer_confirm.xml b/assets/dushanbe/3.2.38/card_transfer_confirm.xml new file mode 100644 index 0000000..8021095 --- /dev/null +++ b/assets/dushanbe/3.2.38/card_transfer_confirm.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/dushanbe/3.2.38/card_transfer_input.xml b/assets/dushanbe/3.2.38/card_transfer_input.xml new file mode 100644 index 0000000..7d3ebfc --- /dev/null +++ b/assets/dushanbe/3.2.38/card_transfer_input.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/dushanbe/3.2.38/card_transfer_success.xml b/assets/dushanbe/3.2.38/card_transfer_success.xml new file mode 100644 index 0000000..b829813 --- /dev/null +++ b/assets/dushanbe/3.2.38/card_transfer_success.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/dushanbe/3.2.38/card_transfer_tx_detail.xml b/assets/dushanbe/3.2.38/card_transfer_tx_detail.xml new file mode 100644 index 0000000..598e9ed --- /dev/null +++ b/assets/dushanbe/3.2.38/card_transfer_tx_detail.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/dushanbe/3.2.38/cards_screen.xml b/assets/dushanbe/3.2.38/cards_screen.xml new file mode 100644 index 0000000..7ec72c1 --- /dev/null +++ b/assets/dushanbe/3.2.38/cards_screen.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/dushanbe/3.2.38/history_screen.xml b/assets/dushanbe/3.2.38/history_screen.xml new file mode 100644 index 0000000..a03504b --- /dev/null +++ b/assets/dushanbe/3.2.38/history_screen.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/dushanbe/3.2.38/home_screen.xml b/assets/dushanbe/3.2.38/home_screen.xml new file mode 100644 index 0000000..b491869 --- /dev/null +++ b/assets/dushanbe/3.2.38/home_screen.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/dushanbe/3.2.38/phone_transfer_confirm.xml b/assets/dushanbe/3.2.38/phone_transfer_confirm.xml new file mode 100644 index 0000000..2697337 --- /dev/null +++ b/assets/dushanbe/3.2.38/phone_transfer_confirm.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/dushanbe/3.2.38/transfers_screen.xml b/assets/dushanbe/3.2.38/transfers_screen.xml new file mode 100644 index 0000000..d5d87e8 --- /dev/null +++ b/assets/dushanbe/3.2.38/transfers_screen.xml @@ -0,0 +1 @@ + \ No newline at end of file