From 2c808146824b0ca4b05b3d08c33c3a113e1c7c0e Mon Sep 17 00:00:00 2001 From: uncor3 Date: Sun, 27 Jul 2025 12:33:33 +0000 Subject: [PATCH] improve paired device flow --- src/appcontext.cpp | 43 +++++++++------------- src/appcontext.h | 5 ++- src/iDescriptor.h | 2 ++ src/mainwindow.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 108 insertions(+), 30 deletions(-) diff --git a/src/appcontext.cpp b/src/appcontext.cpp index 2c6a339..864ea27 100644 --- a/src/appcontext.cpp +++ b/src/appcontext.cpp @@ -64,12 +64,10 @@ void AppContext::handleDBusSignal(const QDBusMessage &msg) } } -void AppContext::addDevice(QString udid, idevice_connection_type conn_type) +void AppContext::addDevice(QString udid, idevice_connection_type conn_type, + AddType addType) { try { - // ui->stackedWidget->setCurrentIndex(1); - - // ui->tabWidget->show(); IDescriptorInitDeviceResult initResult = init_idescriptor_device(udid.toStdString().c_str()); @@ -81,10 +79,16 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type) qDebug() << "Failed to initialize device with UDID: " << udid; // return onDeviceInitFailed(udid, initResult.error); if (initResult.error == LOCKDOWN_E_PASSWORD_PROTECTED) { - warn("Device with UDID " + udid + - " is password protected. Please unlock the device and " - "try again.", - "Warning"); + // warn("Device with UDID " + udid + + // " is password protected. Please unlock the device + // and " "try again.", + // "Warning"); + // TODO: also handle pairing devices + // the reason why we don't handle pairing devices here is + // because it's less likely that it will be an error typeof + // LOCKDOWN_E_PASSWORD_PROTECTED if the device is paired type + if (addType == AddType::Regular) + emit devicePairPending(udid); } else if (initResult.error == LOCKDOWN_E_INVALID_HOST_ID) { warn("Device with UDID " + udid + " is not trusted. Please trust this computer on the " @@ -97,7 +101,6 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type) } return; } - // Find the device once using std::find_if iDescriptorDevice *device = new iDescriptorDevice{ .udid = udid.toStdString(), .conn_type = conn_type, @@ -105,29 +108,15 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type) .deviceInfo = initResult.deviceInfo, }; m_devices[device->udid] = device; - emit deviceAdded(device); + if (addType == AddType::Regular) + return emit deviceAdded(device); + emit devicePaired(device); + } catch (const std::exception &e) { qDebug() << "Exception in onDeviceAdded: " << e.what(); // QMessageBox::critical(this, "Error", "An error occurred while // processing device information"); } - - // if (!device) return std::string(); - - // QUuid uuid = QUuid::createUuid(); - // QString uuidNoBraces = uuid.toString(QUuid::WithoutBraces); // - // "3F2504E0-4F89-41D3-9A0C-0305E82C3301" - - // If device already exists, clean up the old one first - // if (m_devices.contains(uuidNoBraces.toStdString())) { - // cleanDevice(m_devices[uuidNoBraces.toStdString()]); - // delete m_devices[uuidNoBraces.toStdString()]; - // } - - // m_devices[uuidNoBraces.toStdString()] = device; - // return true; - // return uuidNoBraces.toStdString(); - // return device->udid; } void AppContext::removeDevice(QString _udid) diff --git a/src/appcontext.h b/src/appcontext.h index 7c6bfb8..2a5100d 100644 --- a/src/appcontext.h +++ b/src/appcontext.h @@ -32,13 +32,16 @@ private: signals: void deviceAdded(iDescriptorDevice *device); void deviceRemoved(const std::string &udid); + void devicePaired(iDescriptorDevice *device); void recoveryDeviceAdded(RecoveryDeviceInfo *deviceInfo); void recoveryDeviceRemoved(const QString &udid); + void devicePairPending(const QString &udid); void systemSleepStarting(); void systemWakeup(); public slots: void removeDevice(QString udid); - void addDevice(QString udid, idevice_connection_type connType); + void addDevice(QString udid, idevice_connection_type connType, + AddType addType); }; #endif // APPCONTEXT_H diff --git a/src/iDescriptor.h b/src/iDescriptor.h index 0ebeb61..d94aeb0 100644 --- a/src/iDescriptor.h +++ b/src/iDescriptor.h @@ -161,6 +161,8 @@ struct IDescriptorInitDeviceResultRecovery { void warn(const QString &message, const QString &title = "Warning", QWidget *parent = nullptr); +enum class AddType { Regular, Pairing }; + #define APP_LABEL "iDescriptor" #define APP_VERSION "0.0.1" #define APP_COPYRIGHT "© 2023 Uncore. All rights reserved." \ No newline at end of file diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 1bb4edc..c8fc9d1 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -56,7 +56,8 @@ void handleCallback(const idevice_event_t *event, void *userData) QMetaObject::invokeMethod( AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection, Q_ARG(QString, QString::fromUtf8(event->udid)), - Q_ARG(idevice_connection_type, event->conn_type)); + Q_ARG(idevice_connection_type, event->conn_type), + Q_ARG(AddType, AddType::Regular)); break; } @@ -78,7 +79,8 @@ void handleCallback(const idevice_event_t *event, void *userData) QMetaObject::invokeMethod( AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection, Q_ARG(QString, QString::fromUtf8(event->udid)), - Q_ARG(idevice_connection_type, event->conn_type)); + Q_ARG(idevice_connection_type, event->conn_type), + Q_ARG(AddType, AddType::Pairing)); break; } default: @@ -234,6 +236,88 @@ MainWindow::MainWindow(QWidget *parent) updateNoDevicesConnected(); }); + connect( + AppContext::sharedInstance(), &AppContext::devicePairPending, this, + [this](const QString &udid) { + QWidget *placeholderWidget = new QWidget(); + QVBoxLayout *layout = new QVBoxLayout(placeholderWidget); + QLabel *label = new QLabel( + "Device is not paired. Please pair the device to continue."); + label->setAlignment(Qt::AlignCenter); + layout->addWidget(label); + placeholderWidget->setLayout(layout); + m_device_menu_widgets[udid.toStdString()] = placeholderWidget; + + // DeviceTabWidget *customTabWidget = + // qobject_cast(ui->tabWidget); + + // QString tabTitle = QString::fromStdString(udid.toStdString()); + // QPixmap placeholderIcon(16, 16); + // placeholderIcon.fill(Qt::red); + + // int mostRecentDevice = customTabWidget->addTabWithIcon( + // placeholderWidget, placeholderIcon, tabTitle); + int mostRecentDevice = ui->tabWidget->addTab( + placeholderWidget, getDeviceIcon(udid.toStdString()), + QString::fromStdString(udid.toStdString())); + // customTabWidget->setSizePolicy(QSizePolicy::Expanding, + // QSizePolicy::Preferred); + // customTabWidget->setCurrentIndex(mostRecentDevice); + ui->tabWidget->setCurrentIndex(mostRecentDevice); + ui->stackedWidget->setCurrentIndex(1); // Show device list page + }); + + connect(AppContext::sharedInstance(), &AppContext::devicePaired, this, + [this](iDescriptorDevice *device) { + qDebug() << "Device paired:" + << QString::fromStdString(device->udid); + + DeviceMenuWidget *deviceWidget = new DeviceMenuWidget(device); + + // Find the tab index for this device + int tabIndex = -1; + for (int i = 0; i < ui->tabWidget->count(); ++i) { + if (ui->tabWidget->tabText(i) == + QString::fromStdString(device->udid)) { + tabIndex = i; + break; + } + } + + // If tab exists, remove the old widget and tab + if (tabIndex != -1) { + QWidget *oldWidget = ui->tabWidget->widget(tabIndex); + ui->tabWidget->removeTab(tabIndex); + if (oldWidget) + oldWidget->deleteLater(); + } + + DeviceTabWidget *customTabWidget = + qobject_cast(ui->tabWidget); + + QString tabTitle = + QString::fromStdString(device->deviceInfo.productType); + QPixmap placeholderIcon(16, 16); + placeholderIcon.fill(Qt::red); + + int mostRecentDevice = customTabWidget->addTabWithIcon( + deviceWidget, placeholderIcon, tabTitle); + // int mostRecentDevice = ui->tabWidget->addTab( + // placeholderWidget, getDeviceIcon(udid.toStdString()), + // QString::fromStdString(udid.toStdString())); + customTabWidget->setSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Preferred); + customTabWidget->setCurrentIndex(mostRecentDevice); + // ui->tabWidget->setCurrentIndex(mostRecentDevice); + ui->stackedWidget->setCurrentIndex(1); // Show device list page + + // Clean up old mapping and update + if (m_device_menu_widgets.count(device->udid)) { + m_device_menu_widgets[device->udid]->deleteLater(); + } + m_device_menu_widgets[device->udid] = deviceWidget; + }); + connect( AppContext::sharedInstance(), &AppContext::recoveryDeviceRemoved, this, [this](const QString &ecid) {