feat(ui): implement DevModeWidget for iOS 17 and above

This commit is contained in:
uncor3
2026-04-04 10:46:42 +00:00
parent f06c4487ed
commit 54f798e4ac
8 changed files with 127 additions and 20 deletions
+1
View File
@@ -71,6 +71,7 @@
<file>DeveloperDiskImages.json</file>
<file>resources/keychain.mp4</file>
<file>resources/wireless-gallery-import.mp4</file>
<file>resources/dev-mode.mp4</file>
<file>resources/trust.png</file>
</qresource>
</RCC>
BIN
View File
Binary file not shown.
-4
View File
@@ -48,9 +48,6 @@ public:
const QString &downloadPath) const;
// Mount operations
bool mountImage(const QString &version, const iDescriptorDevice *device);
bool unmountImage();
std::pair<QString, QString> getPathsForVersion(const QString &version);
// Signature comparison
@@ -58,7 +55,6 @@ public:
const char *mounted_sig, uint64_t mounted_sig_len);
QByteArray getImageListData() const { return m_imageListJsonData; }
bool mountCompatibleImage(const iDescriptorDevice *device);
QString downloadCompatibleImage(
const std::shared_ptr<iDescriptorDevice> device,
std::function<void(bool, const QString &version)> callback);
+83
View File
@@ -0,0 +1,83 @@
#include "devmodewidget.h"
DevModeWidget::DevModeWidget(std::shared_ptr<iDescriptorDevice> device,
QWidget *parent)
: QDialog{parent}
{
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 20, 0, 0);
mainLayout->setSpacing(0);
m_loadingWidget = new ZLoadingWidget(false, this);
mainLayout->addWidget(m_loadingWidget);
QWidget *contentContainer = new QWidget(this);
QVBoxLayout *contentLayout = new QVBoxLayout(contentContainer);
contentLayout->setContentsMargins(0, 0, 0, 0);
contentLayout->setSpacing(0);
m_loadingWidget->setupContentWidget(contentContainer);
m_mediaPlayer = new QMediaPlayer(this);
m_videoWidget = new QVideoWidget(this);
m_videoWidget->setMinimumSize(300, 500);
m_videoWidget->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Expanding);
m_videoWidget->setAspectRatioMode(Qt::KeepAspectRatio);
m_mediaPlayer->setVideoOutput(m_videoWidget);
connect(m_mediaPlayer,
QOverload<QMediaPlayer::MediaStatus>::of(
&QMediaPlayer::mediaStatusChanged),
[this](QMediaPlayer::MediaStatus status) {
if (status == QMediaPlayer::EndOfMedia) {
m_mediaPlayer->setPosition(0);
m_mediaPlayer->play();
}
});
QLabel *title =
new QLabel("Enable Developer Mode on your iOS device", this);
title->setAlignment(Qt::AlignCenter);
title->setStyleSheet("QLabel { font-size: 18px; font-weight: bold; }");
QLabel *description = new QLabel(
R"(In order to use this feature on your device, you need to enable Developer Mode in the Settings app.
This allows iDescriptor to access advanced features on your device.
Please follow the instructions in the video below to enable Developer Mode.)",
this);
description->setAlignment(Qt::AlignCenter);
description->setWordWrap(true);
QVBoxLayout *textLayout = new QVBoxLayout();
textLayout->setContentsMargins(20, 20, 20, 20);
textLayout->setSpacing(10);
contentLayout->addWidget(title);
textLayout->addWidget(description);
contentLayout->addLayout(textLayout);
contentLayout->addWidget(m_videoWidget);
m_mediaPlayer->setSource(QUrl("qrc:/resources/dev-mode.mp4"));
connect(
device->service_manager,
&CXX::ServiceManager::developer_mode_option_revealed, this,
[this](bool revealed) {
if (revealed) {
QTimer::singleShot(500, this, &DevModeWidget::init);
} else {
m_loadingWidget->showError(
"Failed to reveal Developer Mode option in UI. Please try "
"again later.");
}
},
Qt::SingleShotConnection);
device->service_manager->reveal_developer_mode_option_in_ui();
}
void DevModeWidget::init()
{
m_mediaPlayer->play();
m_loadingWidget->stop();
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef DEVMODEWIDGET_H
#define DEVMODEWIDGET_H
#include "iDescriptor-ui.h"
#include "iDescriptor.h"
#include "zloadingwidget.h"
#include <QDialog>
#include <QMediaPlayer>
#include <QTimer>
#include <QVBoxLayout>
#include <QVideoWidget>
#include <QWidget>
class DevModeWidget : public QDialog
{
Q_OBJECT
public:
explicit DevModeWidget(std::shared_ptr<iDescriptorDevice> device,
QWidget *parent = nullptr);
private:
ZLoadingWidget *m_loadingWidget;
QMediaPlayer *m_mediaPlayer;
QVideoWidget *m_videoWidget;
void init();
};
#endif // DEVMODEWIDGET_H
+3 -1
View File
@@ -10,7 +10,7 @@ ExportAlbum::ExportAlbum(const std::shared_ptr<iDescriptorDevice> device,
setupWinWindow(this);
#endif
m_loadingWidget = new ZLoadingWidget(true, this);
m_loadingWidget = new ZLoadingWidget(false, this);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(m_loadingWidget);
@@ -99,6 +99,8 @@ void ExportAlbum::getTotalPhotoCount(const QStringList &paths)
watcher->setFuture(QtConcurrent::run([this, paths]() {
size_t count = 0;
bool errorOccurred = false;
// FIXME: if a dir returns empty, it could be an error or just an empty
// dir, we should check that
for (const QString &path : paths) {
QList<QString> items = m_device->afc_backend->list_files_flat(path);
+9 -14
View File
@@ -291,7 +291,7 @@ void VirtualLocation::updateInputsFromMap(const QString &latitude,
qDebug() << "Updated inputs from map:" << latitude << "," << longitude;
}
void VirtualLocation::handleEnable()
void VirtualLocation::restoreButtons()
{
QTimer::singleShot(1000, this, [this]() {
m_applyButton->setText("Apply Location");
@@ -324,9 +324,8 @@ void VirtualLocation::onApplyClicked()
this,
[this, latitude, longitude, devDiskImageHelper](bool success) {
if (!success) {
// mounter will show its own error message, just
// re-enable the button here
return handleEnable();
// mounter will show its own error message
return;
}
u_int32_t set_location_success =
@@ -344,17 +343,16 @@ void VirtualLocation::onApplyClicked()
QMessageBox::information(
this, "Success", "Location applied successfully!");
// SettingsManager::sharedInstance()->saveRecentLocation(
// latitude, longitude);
SettingsManager::sharedInstance()->saveRecentLocation(
latitude, longitude);
}
return handleEnable();
});
connect(devDiskImageHelper, &DevDiskImageHelper::destroyed, this,
&VirtualLocation::handleEnable, Qt::SingleShotConnection);
&VirtualLocation::restoreButtons, Qt::SingleShotConnection);
return devDiskImageHelper->start();
}
// /* iOS 17 and above */
/* iOS 17 and above */
int32_t set_location_res =
m_device->service_manager->set_location(latitude, longitude);
@@ -364,10 +362,7 @@ void VirtualLocation::onApplyClicked()
"Location applied successfully");
break;
case ServiceNotFoundErrorCode:
// TODO: create a widget for this
qDebug() << "Failed to set location simulation: service not found";
QMessageBox::warning(this, "Error",
"Developer Mode is not enabled on the device.");
DevModeWidget(m_device, this).exec();
break;
case TimeoutErrorCode:
qDebug() << "Failed to set location simulation: timed out";
@@ -381,7 +376,7 @@ void VirtualLocation::onApplyClicked()
QString::number(set_location_res));
}
handleEnable();
restoreButtons();
}
void VirtualLocation::loadRecentLocations(QVBoxLayout *layout)
+2 -1
View File
@@ -21,6 +21,7 @@
#define VIRTUAL_LOCATION_H
#include "devdiskimagehelper.h"
#include "devmodewidget.h"
#include "iDescriptor-ui.h"
#include "iDescriptor.h"
#include <QGroupBox>
@@ -57,7 +58,7 @@ private:
void addLocationButtons(QLayout *layout,
QList<QVariantMap> recentLocations);
void handleEnable();
void restoreButtons();
QQuickWidget *m_quickWidget;
QLineEdit *m_latitudeEdit;