#include "WifiConnectDialog.h" #include #include #include #include #include #include #include #include #include #include #include "adb/AdbUtils.h" #include "dao/WifiConnectionDAO.h" WifiConnectDialog::WifiConnectDialog(QWidget *parent) : QDialog(parent) { setWindowTitle("Подключить по Wi-Fi"); setModal(true); auto *form = new QFormLayout; m_ip = new QLineEdit(this); m_ip->setPlaceholderText("192.168.1.50"); m_port = new QLineEdit(this); m_port->setPlaceholderText("37123"); m_port->setValidator(new QIntValidator(1, 65535, this)); m_code = new QLineEdit(this); m_code->setPlaceholderText("6-значный код"); form->addRow("IP", m_ip); form->addRow("Порт", m_port); form->addRow("Код", m_code); m_btn = new QPushButton("Подключить", this); connect(m_btn, &QPushButton::clicked, this, &WifiConnectDialog::onConnect); m_status = new QLabel(this); m_status->setWordWrap(true); m_status->setStyleSheet("color: #555; font-size: 11px;"); auto *layout = new QVBoxLayout(this); layout->addLayout(form); layout->addWidget(m_btn); layout->addWidget(m_status); // Подсказка оператору: где взять реквизиты. auto *hint = new QLabel( "Телефон → Для разработчиков → Беспроводная отладка →\n" "«Подключение с помощью кода»: введите показанные IP:порт и код.", this); hint->setWordWrap(true); hint->setStyleSheet("color: #888; font-size: 10px;"); layout->addWidget(hint); } void WifiConnectDialog::setStatus(const QString &text) { if (m_status) m_status->setText(text); } void WifiConnectDialog::onConnect() { const QString ip = m_ip->text().trimmed(); const int port = m_port->text().trimmed().toInt(); const QString code = m_code->text().trimmed(); if (ip.isEmpty() || port <= 0 || code.isEmpty()) { setStatus("Заполните IP, порт и код."); return; } m_btn->setEnabled(false); setStatus("Спаривание и подключение…"); // Лоадер на время онбординга (бесконечный индикатор, без кнопки отмены). auto *progress = new QProgressDialog("Спаривание и подключение…", QString(), 0, 0, this); progress->setWindowTitle("Подключение по Wi-Fi"); progress->setWindowModality(Qt::WindowModal); progress->setCancelButton(nullptr); progress->setMinimumDuration(0); progress->setAutoClose(false); progress->setAutoReset(false); progress->setWindowFlags(progress->windowFlags() & ~Qt::WindowCloseButtonHint & ~Qt::WindowContextHelpButtonHint); progress->show(); // Результат онбординга, заполняется в фоновом потоке. struct Res { bool ok = false; QString msg; }; auto *res = new Res; auto *worker = QThread::create([res, ip, port, code]() { if (!AdbUtils::adbPair(ip, port, code)) { res->msg = "Не удалось спарить — проверьте порт и код (код одноразовый, " "переоткройте экран спаривания на телефоне)."; return; } // Connect: сначала тем же портом, при неудаче — поиск connect-порта через mDNS. QString endpoint = AdbUtils::adbConnect(ip, port); if (endpoint.isEmpty()) { if (const QString mep = AdbUtils::mdnsFindConnect(ip); !mep.isEmpty()) { const int c = mep.lastIndexOf(':'); endpoint = AdbUtils::adbConnect(mep.left(c), mep.mid(c + 1).toInt()); } } if (endpoint.isEmpty()) { res->msg = "Спарено, но не удалось подключиться. Проверьте порт подключения " "(в «Беспроводной отладке» он отличается от порта спаривания)."; return; } const QString androidId = AdbUtils::getAndroidId(endpoint); if (androidId.isEmpty()) { res->msg = "Подключено (" + endpoint + "), но не удалось прочитать android_id."; return; } const int connectPort = endpoint.mid(endpoint.lastIndexOf(':') + 1).toInt(); // Код НЕ сохраняем — он одноразовый, для реконнекта не нужен. WifiConnectionDAO::upsert(androidId, ip, connectPort); res->ok = true; res->msg = "Подключено: " + endpoint + ". Устройство появится в списке."; }); QPointer guard(this); QPointer progressGuard(progress); connect(worker, &QThread::finished, qApp, [worker, res, guard, progressGuard]() { if (progressGuard) { progressGuard->reset(); progressGuard->deleteLater(); } if (guard) { guard->setStatus(res->msg); guard->m_btn->setEnabled(true); if (res->ok) { guard->m_code->clear(); // код одноразовый — очистим для следующего ввода } } delete res; worker->deleteLater(); }); worker->start(); }