mirror of
https://github.com/iDescriptor/iDescriptor.git
synced 2026-06-22 03:45:51 +08:00
refactor dev disk mounting
This commit is contained in:
+156
-181
@@ -51,189 +51,179 @@ void DevDiskImageHelper::setupUI()
|
||||
mainLayout->setContentsMargins(20, 20, 20, 20);
|
||||
mainLayout->setSpacing(15);
|
||||
|
||||
// ZLoadingWidget handles the spinner + state switching
|
||||
m_loadingWidget = new ZLoadingWidget(true, this);
|
||||
mainLayout->addWidget(m_loadingWidget);
|
||||
connect(m_loadingWidget, &ZLoadingWidget::retryClicked, this,
|
||||
&DevDiskImageHelper::onRetryButtonClicked);
|
||||
|
||||
// Custom error layout: message + Retry
|
||||
auto *errorLayout = new QHBoxLayout();
|
||||
errorLayout->addStretch();
|
||||
auto *contentLayout = new QHBoxLayout();
|
||||
contentLayout->addStretch();
|
||||
|
||||
m_statusLabel = new QLabel("An error occurred.");
|
||||
m_statusLabel = new QLabel("Please wait...");
|
||||
m_statusLabel->setWordWrap(true);
|
||||
m_statusLabel->setAlignment(Qt::AlignCenter);
|
||||
errorLayout->addWidget(m_statusLabel);
|
||||
contentLayout->addWidget(m_statusLabel);
|
||||
contentLayout->addStretch();
|
||||
|
||||
m_retryButton = new QPushButton("Retry");
|
||||
connect(m_retryButton, &QPushButton::clicked, this,
|
||||
&DevDiskImageHelper::onRetryButtonClicked);
|
||||
errorLayout->addWidget(m_retryButton);
|
||||
|
||||
errorLayout->addStretch();
|
||||
|
||||
// Register custom error layout with ZLoadingWidget
|
||||
m_loadingWidget->setupErrorWidget(errorLayout);
|
||||
|
||||
// Bottom button row (Cancel / Close)
|
||||
auto *buttonLayout = new QHBoxLayout();
|
||||
buttonLayout->addStretch();
|
||||
|
||||
m_cancelButton = new QPushButton("Cancel");
|
||||
connect(m_cancelButton, &QPushButton::clicked, this, &QDialog::reject);
|
||||
buttonLayout->addWidget(m_cancelButton);
|
||||
|
||||
buttonLayout->addStretch();
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
m_loadingWidget->setupContentWidget(contentLayout);
|
||||
mainLayout->addWidget(m_loadingWidget);
|
||||
|
||||
setMinimumWidth(400);
|
||||
setMinimumHeight(200);
|
||||
setModal(true);
|
||||
show();
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::start()
|
||||
/* try to mount a specific version */
|
||||
void DevDiskImageHelper::mountVersion(const QString &version)
|
||||
{
|
||||
if (m_cancelButton) {
|
||||
m_cancelButton->setText("Cancel");
|
||||
}
|
||||
if (m_loadingWidget) {
|
||||
m_loadingWidget->showLoading();
|
||||
}
|
||||
showStatus("Please wait...");
|
||||
|
||||
m_loadingWidget->stop();
|
||||
m_statusLabel->setText("Please wait...");
|
||||
m_version = version;
|
||||
unsigned int deviceMajorVersion =
|
||||
m_device->deviceInfo.parsedDeviceVersion.major;
|
||||
|
||||
// FIXME:we dont have developer disk images for ios 6 and below
|
||||
if (deviceMajorVersion > 5) {
|
||||
const bool isMountAvailable =
|
||||
DevDiskManager::sharedInstance()->downloadCompatibleImage(
|
||||
m_device, [this](bool success) {
|
||||
if (success) {
|
||||
checkAndMount();
|
||||
} else {
|
||||
finishWithError("Failed to download compatible image.");
|
||||
}
|
||||
});
|
||||
qDebug() << "isMountAvailable:" << isMountAvailable;
|
||||
if (!isMountAvailable) {
|
||||
finishWithError(
|
||||
"There is no compatible developer disk image available for " +
|
||||
QString::number(deviceMajorVersion) + ".");
|
||||
}
|
||||
} else {
|
||||
showStatus("Developer disk image is not available for iOS version " +
|
||||
QString::number(deviceMajorVersion) +
|
||||
". Please use a device with iOS 6 or above.",
|
||||
true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::checkAndMount()
|
||||
{
|
||||
connect(
|
||||
m_device->service_manager,
|
||||
&CXX::ServiceManager::mounted_image_retrieved, this,
|
||||
[this](QByteArray signature, u_int64_t sig_length) {
|
||||
[this, deviceMajorVersion, version](bool success, bool locked,
|
||||
QByteArray signature,
|
||||
u_int64_t sig_length) {
|
||||
if (!success) {
|
||||
if (locked) {
|
||||
qDebug() << "Failed to retrieve mounted image signature: "
|
||||
"device is locked.";
|
||||
m_loadingWidget->showError(
|
||||
"The device appears to be locked. Please unlock the "
|
||||
"device and try again.");
|
||||
return;
|
||||
}
|
||||
qDebug() << "Failed to retrieve mounted image signature.";
|
||||
m_loadingWidget->showError(
|
||||
"Failed to retrieve mounted image signature.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!signature.isEmpty() || sig_length > 0) {
|
||||
qDebug()
|
||||
<< "Developer disk image already mounted with signature:"
|
||||
<< "length:" << sig_length << "signature:" << signature;
|
||||
finishWithSuccess();
|
||||
m_loadingWidget->showError(
|
||||
"A developer disk image already mounted. "
|
||||
"Please restart the device and try again.");
|
||||
} else {
|
||||
onMountButtonClicked();
|
||||
const QString downloadPath =
|
||||
SettingsManager::sharedInstance()->devdiskimgpath();
|
||||
const bool isDownloaded =
|
||||
DevDiskManager::sharedInstance()->isImageDownloaded(
|
||||
version, downloadPath);
|
||||
|
||||
qDebug() << "isDownloaded:" << isDownloaded;
|
||||
if (!isDownloaded) {
|
||||
m_loadingWidget->showError(
|
||||
"The developer disk image for iOS " + version +
|
||||
" is not downloaded. Please download it first.");
|
||||
} else {
|
||||
handleMounting(version);
|
||||
}
|
||||
}
|
||||
},
|
||||
Qt::SingleShotConnection);
|
||||
m_device->service_manager->get_mounted_image();
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::onMountButtonClicked()
|
||||
/* mount a compatible version */
|
||||
void DevDiskImageHelper::start()
|
||||
{
|
||||
QString path = SettingsManager::sharedInstance()->mkDevDiskImgPath();
|
||||
m_loadingWidget->stop();
|
||||
m_statusLabel->setText("Please wait...");
|
||||
|
||||
if (m_loadingWidget) {
|
||||
m_loadingWidget->showLoading();
|
||||
}
|
||||
|
||||
// Check if we need to download first
|
||||
unsigned int deviceMajorVersion =
|
||||
m_device->deviceInfo.parsedDeviceVersion.major;
|
||||
unsigned int deviceMinorVersion =
|
||||
m_device->deviceInfo.parsedDeviceVersion.minor;
|
||||
|
||||
QList<ImageInfo> images = DevDiskManager::sharedInstance()->parseImageList(
|
||||
path, deviceMajorVersion, deviceMinorVersion, "", 0);
|
||||
|
||||
// Check if compatible image is downloaded
|
||||
bool hasDownloadedImage = false;
|
||||
QString versionToMount;
|
||||
|
||||
for (const ImageInfo &info : images) {
|
||||
if (info.compatibility == ImageCompatibility::Compatible ||
|
||||
info.compatibility == ImageCompatibility::MaybeCompatible) {
|
||||
if (info.isDownloaded) {
|
||||
hasDownloadedImage = true;
|
||||
versionToMount = info.version;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDownloadedImage) {
|
||||
// // Mount directly
|
||||
m_downloadingVersion = versionToMount;
|
||||
showStatus("Mounting developer disk image...");
|
||||
onImageDownloadFinished(versionToMount, true, "");
|
||||
// FIXME:we dont have developer disk images for ios 6 and below
|
||||
if (deviceMajorVersion > 5) {
|
||||
checkAndMount();
|
||||
} else {
|
||||
// Need to download first
|
||||
showStatus(
|
||||
"Downloading developer disk image...\nThis may take a moment.");
|
||||
|
||||
// Connect to download signals
|
||||
connect(DevDiskManager::sharedInstance(),
|
||||
&DevDiskManager::imageDownloadFinished, this,
|
||||
&DevDiskImageHelper::onImageDownloadFinished,
|
||||
Qt::UniqueConnection);
|
||||
|
||||
// Find version to download
|
||||
for (const ImageInfo &info : images) {
|
||||
if (info.compatibility == ImageCompatibility::Compatible ||
|
||||
info.compatibility == ImageCompatibility::MaybeCompatible) {
|
||||
m_downloadingVersion = info.version;
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_loadingWidget->showError(
|
||||
"Developer disk image is not available for iOS version " +
|
||||
QString::number(deviceMajorVersion) +
|
||||
". Please use a device with iOS 6 or above.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::onImageDownloadFinished(const QString &version,
|
||||
bool success,
|
||||
const QString &errorMessage)
|
||||
void DevDiskImageHelper::checkAndMount()
|
||||
{
|
||||
if (version != m_downloadingVersion) {
|
||||
qDebug() << "Ignoring download finished for version" << version
|
||||
<< "expected" << m_downloadingVersion;
|
||||
return;
|
||||
}
|
||||
unsigned int deviceMajorVersion =
|
||||
m_device->deviceInfo.parsedDeviceVersion.major;
|
||||
|
||||
if (!success) {
|
||||
showRetryUI("Failed to download developer disk image:\n" +
|
||||
errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
showStatus("Download complete. Mounting...");
|
||||
connect(
|
||||
m_device->service_manager,
|
||||
&CXX::ServiceManager::mounted_image_retrieved, this,
|
||||
[this, deviceMajorVersion](bool success, bool locked,
|
||||
QByteArray signature, u_int64_t sig_length) {
|
||||
qDebug() << "[ DevDiskImageHelper::checkAndMount] qobject::connect "
|
||||
"of mounted_image_retrieved consumed";
|
||||
if (!success) {
|
||||
if (locked) {
|
||||
qDebug() << "Failed to retrieve mounted image signature: "
|
||||
"device is locked.";
|
||||
m_loadingWidget->showError(
|
||||
"The device appears to be locked. Please unlock the "
|
||||
"device and try again.");
|
||||
return;
|
||||
}
|
||||
qDebug() << "Failed to retrieve mounted image info.";
|
||||
m_loadingWidget->showError(
|
||||
"Failed to retrieve mounted image info.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!signature.isEmpty() || sig_length > 0) {
|
||||
qDebug()
|
||||
<< "Developer disk image already mounted with signature:"
|
||||
<< "length:" << sig_length << "signature:" << signature;
|
||||
finishWithSuccess();
|
||||
} else {
|
||||
const QString version =
|
||||
DevDiskManager::sharedInstance()->downloadCompatibleImage(
|
||||
m_device, [this](bool success, const QString &version) {
|
||||
if (success) {
|
||||
handleMounting(version);
|
||||
} else {
|
||||
m_loadingWidget->showError(
|
||||
"Failed to download compatible image.");
|
||||
}
|
||||
});
|
||||
m_version = version;
|
||||
qDebug() << "Is there a compatible image ?"
|
||||
<< !version.isEmpty();
|
||||
if (version.isEmpty()) {
|
||||
// FIXME: we need to disable the retry button in this case
|
||||
m_loadingWidget->showError(
|
||||
"There is no compatible developer disk "
|
||||
"image available for " +
|
||||
QString::number(deviceMajorVersion) + ".");
|
||||
} else {
|
||||
m_statusLabel->setText(
|
||||
QString("Downloading compatible developer disk "
|
||||
"image for iOS %1..")
|
||||
.arg(deviceMajorVersion));
|
||||
}
|
||||
}
|
||||
},
|
||||
Qt::SingleShotConnection);
|
||||
m_device->service_manager->get_mounted_image();
|
||||
}
|
||||
// todo called twice
|
||||
// finishWithSuccess called with wait = false
|
||||
void DevDiskImageHelper::handleMounting(const QString &version)
|
||||
{
|
||||
m_statusLabel->setText("Mounting...");
|
||||
auto paths = DevDiskManager::sharedInstance()->getPathsForVersion(version);
|
||||
qDebug() << "Mounting image with paths:" << paths.first << paths.second;
|
||||
|
||||
// FIXME
|
||||
// err->code == DeviceLockedMountErrorCode
|
||||
// check for error code
|
||||
connect(
|
||||
m_device->service_manager, &CXX::ServiceManager::dev_image_mounted,
|
||||
this,
|
||||
[this](bool success) {
|
||||
[this](bool success, bool isLocked) {
|
||||
qDebug() << "[devdiskimagehelper] : Developer disk image "
|
||||
"mount result:"
|
||||
<< success;
|
||||
@@ -242,12 +232,25 @@ void DevDiskImageHelper::onImageDownloadFinished(const QString &version,
|
||||
"mounted successfully.";
|
||||
finishWithSuccess(true);
|
||||
} else {
|
||||
qDebug() << "[devdiskimagehelper] : Failed to mount developer "
|
||||
"disk image.";
|
||||
showRetryUI(
|
||||
"Failed to mount developer disk image.\n"
|
||||
"Please ensure the device is unlocked and using a genuine "
|
||||
"cable.");
|
||||
if (isLocked) {
|
||||
qDebug() << "[devdiskimagehelper] : Failed to mount "
|
||||
"developer disk image: device is locked.";
|
||||
m_loadingWidget->showError(
|
||||
"Failed to mount developer disk image.\n"
|
||||
"The device appears to be locked. Please unlock the "
|
||||
"device and try again.");
|
||||
return;
|
||||
} else {
|
||||
|
||||
qDebug()
|
||||
<< "[devdiskimagehelper] : Failed to mount developer "
|
||||
"disk image.";
|
||||
m_loadingWidget->showError(
|
||||
"Failed to mount developer disk image.\n"
|
||||
"Please ensure the device is unlocked and "
|
||||
"using a genuine "
|
||||
"cable.");
|
||||
}
|
||||
}
|
||||
},
|
||||
Qt::SingleShotConnection);
|
||||
@@ -255,41 +258,18 @@ void DevDiskImageHelper::onImageDownloadFinished(const QString &version,
|
||||
m_device->service_manager->mount_dev_image(paths.first, paths.second);
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::showRetryUI(const QString &errorMessage)
|
||||
{
|
||||
if (m_statusLabel) {
|
||||
m_statusLabel->setText(errorMessage);
|
||||
}
|
||||
if (m_loadingWidget) {
|
||||
m_loadingWidget->showError();
|
||||
}
|
||||
if (m_cancelButton) {
|
||||
m_cancelButton->setText("Close");
|
||||
}
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::onRetryButtonClicked()
|
||||
{
|
||||
if (m_cancelButton) {
|
||||
m_cancelButton->setText("Cancel");
|
||||
}
|
||||
if (m_loadingWidget) {
|
||||
m_loadingWidget->showLoading();
|
||||
}
|
||||
QTimer::singleShot(200, this, &DevDiskImageHelper::start);
|
||||
}
|
||||
m_loadingWidget->showLoading();
|
||||
|
||||
void DevDiskImageHelper::showStatus(const QString &message, bool isError)
|
||||
{
|
||||
if (isError) {
|
||||
showRetryUI(message);
|
||||
} else {
|
||||
if (m_statusLabel) {
|
||||
m_statusLabel->setText(message);
|
||||
QTimer::singleShot(200, this, [this]() {
|
||||
if (!m_version.isEmpty()) {
|
||||
qDebug() << "Retrying mount for version:" << m_version;
|
||||
mountVersion(m_version);
|
||||
} else {
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
show();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -311,8 +291,3 @@ void DevDiskImageHelper::finishWithSuccess(bool wait)
|
||||
}
|
||||
handler();
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::finishWithError(const QString &errorMessage)
|
||||
{
|
||||
showRetryUI(errorMessage);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "iDescriptor-ui.h"
|
||||
#include "iDescriptor.h"
|
||||
#include "settingsmanager.h"
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
@@ -38,7 +39,18 @@ public:
|
||||
|
||||
// Start the mounting process
|
||||
void start();
|
||||
void mountVersion(const QString &version);
|
||||
|
||||
static bool
|
||||
canMountForDevice(const std::shared_ptr<iDescriptorDevice> device)
|
||||
{
|
||||
/*
|
||||
iOS 17 and later are not supported
|
||||
even though there are some images called "Personalized Disk Images"
|
||||
but we dont support them for now
|
||||
*/
|
||||
return device->ios_version < 17;
|
||||
}
|
||||
signals:
|
||||
void mountingCompleted(bool success);
|
||||
void downloadStarted();
|
||||
@@ -46,27 +58,22 @@ signals:
|
||||
|
||||
private slots:
|
||||
void checkAndMount();
|
||||
void onMountButtonClicked();
|
||||
void onRetryButtonClicked();
|
||||
void onImageDownloadFinished(const QString &version, bool success,
|
||||
const QString &errorMessage);
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
void showStatus(const QString &message, bool isError = false);
|
||||
void showMountUI();
|
||||
void showRetryUI(const QString &errorMessage);
|
||||
void finishWithSuccess(bool wait = false);
|
||||
void finishWithError(const QString &errorMessage);
|
||||
void handleMounting(const QString &version);
|
||||
|
||||
const std::shared_ptr<iDescriptorDevice> m_device;
|
||||
|
||||
QLabel *m_statusLabel;
|
||||
ZLoadingWidget *m_loadingWidget;
|
||||
QPushButton *m_retryButton;
|
||||
QPushButton *m_cancelButton;
|
||||
|
||||
QString m_downloadingVersion;
|
||||
|
||||
// set when called with mountVersion
|
||||
QString m_version = QString();
|
||||
};
|
||||
|
||||
#endif // DEVDISKIMAGEHELPER_H
|
||||
|
||||
+78
-162
@@ -168,12 +168,11 @@ void DevDiskImagesWidget::onDeviceSelectionChanged(int index)
|
||||
index >= AppContext::sharedInstance()->getAllDevices().size())
|
||||
return;
|
||||
|
||||
return;
|
||||
// auto device = AppContext::sharedInstance()->getAllDevices()[index];
|
||||
// if (device == nullptr)
|
||||
// return;
|
||||
auto device = AppContext::sharedInstance()->getAllDevices()[index];
|
||||
if (device == nullptr)
|
||||
return;
|
||||
|
||||
// m_currentDeviceUdid = QString::fromStdString(device->udid);
|
||||
m_currentDeviceUdid = device->udid;
|
||||
displayImages();
|
||||
}
|
||||
|
||||
@@ -578,106 +577,28 @@ void DevDiskImagesWidget::onMountButtonClicked()
|
||||
|
||||
void DevDiskImagesWidget::mountImage(const QString &version)
|
||||
{
|
||||
// FIXME: wireup
|
||||
// QString udid = m_deviceComboBox->currentData().toString();
|
||||
// m_deviceComboBox->setEnabled(false);
|
||||
// if (udid.isEmpty()) {
|
||||
// QMessageBox::warning(this, "No Device", "Please select a device.");
|
||||
// return;
|
||||
// }
|
||||
QString udid = m_deviceComboBox->currentData().toString();
|
||||
m_deviceComboBox->setEnabled(false);
|
||||
|
||||
// if (!DevDiskManager::sharedInstance()->isImageDownloaded(
|
||||
// version, SettingsManager::sharedInstance()->devdiskimgpath())) {
|
||||
// QMessageBox::warning(
|
||||
// this, "Image Not Found",
|
||||
// QString("The selected disk image for version %1 is not
|
||||
// downloaded. "
|
||||
// "Please download it first.")
|
||||
// .arg(version));
|
||||
// return;
|
||||
// }
|
||||
if (udid.isEmpty()) {
|
||||
QMessageBox::warning(this, "No Device", "Please select a device.");
|
||||
return;
|
||||
}
|
||||
std::shared_ptr<iDescriptorDevice> device =
|
||||
AppContext::sharedInstance()->getDevice(udid);
|
||||
|
||||
// m_mountButton->setEnabled(false);
|
||||
// m_mountButton->setText("Mounting...");
|
||||
if (!device) {
|
||||
QMessageBox::warning(this, "Device Not Found",
|
||||
"The selected device could not be found.");
|
||||
return;
|
||||
}
|
||||
|
||||
// auto updateUI = [&]() {
|
||||
// m_mountButton->setEnabled(true);
|
||||
// m_mountButton->setText("Mount");
|
||||
// m_deviceComboBox->setEnabled(true);
|
||||
// };
|
||||
|
||||
// auto paths =
|
||||
// DevDiskManager::sharedInstance()->getPathsForVersion(version);
|
||||
|
||||
// MountedImageInfo info = ServiceManager::getMountedImage(
|
||||
// AppContext::sharedInstance()->getDevice(udid.toStdString()));
|
||||
|
||||
// if (info.err == nullptr && info.signature && info.signature_len) {
|
||||
// qDebug() << "Mount image: already mounted sig found"
|
||||
// << QString::fromStdString(std::string((char
|
||||
// *)info.signature,
|
||||
// info.signature_len));
|
||||
// QMessageBox::information(this, "Already Mounted",
|
||||
// QString("A developer disk image is already "
|
||||
// "mounted on %1.")
|
||||
// .arg(m_deviceComboBox->currentText()));
|
||||
// return updateUI();
|
||||
// } else if (info.err->code == DeviceLockedMountErrorCode) {
|
||||
// /* Never returns DeviceLockedMountErrorCode when doing
|
||||
// image_mounter_lookup_image but maybe used in future */
|
||||
// } else if (info.err->code == NotFoundErrorCode) {
|
||||
// // OK, no image mounted
|
||||
// qDebug() << "Mount image: no mounted image found";
|
||||
// } else {
|
||||
// QMessageBox::critical(
|
||||
// this, "Mount Check Failed",
|
||||
// QString("Failed to check mounted image on %1. Try with a "
|
||||
// "genuine cable.")
|
||||
// .arg(m_deviceComboBox->currentText()));
|
||||
// mounted_image_info_free(info);
|
||||
// return updateUI();
|
||||
// }
|
||||
|
||||
// mounted_image_info_free(info);
|
||||
|
||||
// iDescriptorDevice *currentDevice =
|
||||
// m_currentDeviceUdid.isEmpty() ? nullptr
|
||||
// :
|
||||
// AppContext::sharedInstance()->getDevice(
|
||||
// m_currentDeviceUdid.toStdString());
|
||||
|
||||
// if (!currentDevice) {
|
||||
// QMessageBox::warning(this, "No Device",
|
||||
// "Device is no longer connected.");
|
||||
// return updateUI();
|
||||
// }
|
||||
|
||||
// IdeviceFfiError *err = ServiceManager::mountImage(
|
||||
// currentDevice, paths.first.toStdString().c_str(),
|
||||
// paths.second.toStdString().c_str());
|
||||
|
||||
// if (err == nullptr) {
|
||||
// QMessageBox::information(this, "Success",
|
||||
// QString("Image mounted successfully on %1.")
|
||||
// .arg(m_deviceComboBox->currentText()));
|
||||
// return updateUI();
|
||||
// }
|
||||
|
||||
// qDebug() << "Mount image result:" << err->code
|
||||
// << QString::fromStdString(err->message);
|
||||
|
||||
// if (err->code == DeviceLockedMountErrorCode) {
|
||||
// QMessageBox::critical(this, "Mount Failed",
|
||||
// "The device is locked. Please unlock it and
|
||||
// try" " again.");
|
||||
// } else {
|
||||
// QMessageBox::critical(
|
||||
// this, "Mount Failed",
|
||||
// QString("Failed to mount image on %1. Try with a genuine cable.")
|
||||
// .arg(m_deviceComboBox->currentText()));
|
||||
// }
|
||||
// idevice_error_free(err);
|
||||
// updateUI();
|
||||
auto *helper = new DevDiskImageHelper(device, this);
|
||||
connect(helper, &DevDiskImageHelper::finished, this, [this, helper]() {
|
||||
m_deviceComboBox->setEnabled(true);
|
||||
displayImages(); // Refresh
|
||||
});
|
||||
helper->mountVersion(version);
|
||||
}
|
||||
|
||||
void DevDiskImagesWidget::closeEvent(QCloseEvent *event)
|
||||
@@ -711,67 +632,62 @@ void DevDiskImagesWidget::closeEvent(QCloseEvent *event)
|
||||
|
||||
void DevDiskImagesWidget::checkMountedImage()
|
||||
{
|
||||
// FIXME: wireup
|
||||
// iDescriptorDevice *currentDevice =
|
||||
// m_currentDeviceUdid.isEmpty() ? nullptr
|
||||
// :
|
||||
// AppContext::sharedInstance()->getDevice(
|
||||
// m_currentDeviceUdid.toStdString());
|
||||
QString udid = m_deviceComboBox->currentData().toString();
|
||||
m_deviceComboBox->setEnabled(false);
|
||||
|
||||
// if (!currentDevice) {
|
||||
// qDebug() << "No device selected";
|
||||
// auto devices = AppContext::sharedInstance()->getAllDevices();
|
||||
// for (const auto &dev : devices) {
|
||||
// qDebug() << "Device:"
|
||||
// << QString::fromStdString(dev->deviceInfo.deviceName)
|
||||
// << "UDID:" << QString::fromStdString(dev->udid);
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
// if (m_deviceComboBox->currentIndex() < 0) {
|
||||
// qDebug() << "No device selected in combo box";
|
||||
// return;
|
||||
// }
|
||||
if (udid.isEmpty()) {
|
||||
QMessageBox::warning(this, "No Device", "Please select a device.");
|
||||
return;
|
||||
}
|
||||
qDebug() << "Checking mounted image for device UDID:" << udid;
|
||||
std::shared_ptr<iDescriptorDevice> device =
|
||||
AppContext::sharedInstance()->getDevice(udid);
|
||||
|
||||
// /*
|
||||
// older devices return something like this:
|
||||
// {
|
||||
// "ImagePresent": true,
|
||||
// "ImageSignature": <7b16200b 2ead1830 a59809d1 51e9060b ... 8a
|
||||
// 9844eb07 e0b8e0>, "Status": "Complete"
|
||||
// }
|
||||
// */
|
||||
// MountedImageInfo info = ServiceManager::getMountedImage(currentDevice);
|
||||
if (!device) {
|
||||
QMessageBox::warning(this, "Device Not Found",
|
||||
"The selected device could not be found.");
|
||||
return;
|
||||
}
|
||||
|
||||
// if (info.err == nullptr && info.signature != nullptr &&
|
||||
// info.signature_len > 0) {
|
||||
// m_mounted_sig = std::string(
|
||||
// reinterpret_cast<const char *>(info.signature),
|
||||
// info.signature_len);
|
||||
// m_mounted_sig_len = info.signature_len;
|
||||
// displayImages(); // Refresh to show mounted status
|
||||
// QMessageBox::information(
|
||||
// this, "Check Mounted Image",
|
||||
// "There is already a developer disk image mounted on the
|
||||
// device.");
|
||||
// mounted_image_info_free(info);
|
||||
// } else if (info.err->code == DeviceLockedMountErrorCode) {
|
||||
// QMessageBox::critical(this, "Device Locked",
|
||||
// "The device is locked. Please unlock it and
|
||||
// try" " again.");
|
||||
// mounted_image_info_free(info);
|
||||
// } else if (info.err->code == NotFoundErrorCode) {
|
||||
// QMessageBox::critical(
|
||||
// this, "No Mounted Image",
|
||||
// "No developer disk image is mounted on the device.");
|
||||
// mounted_image_info_free(info);
|
||||
// } else {
|
||||
// QMessageBox::critical(
|
||||
// this, "Check Mounted Image Failed",
|
||||
// QString("Failed to check mounted image on %1. Try with a "
|
||||
// "genuine cable. Error message: %2")
|
||||
// .arg(m_deviceComboBox->currentText())
|
||||
// .arg(QString::fromStdString(info.err->message)));
|
||||
// mounted_image_info_free(info);
|
||||
// }
|
||||
connect(
|
||||
device->service_manager, &CXX::ServiceManager::mounted_image_retrieved,
|
||||
this,
|
||||
[this](bool success, bool locked, QByteArray signature,
|
||||
std::uint64_t sig_length) {
|
||||
m_deviceComboBox->setEnabled(true);
|
||||
if (!success) {
|
||||
if (locked) {
|
||||
QMessageBox::warning(
|
||||
this, "Device Locked",
|
||||
"The device appears to be locked. Please unlock the "
|
||||
"device and try again.");
|
||||
return;
|
||||
}
|
||||
QMessageBox::critical(
|
||||
this, "Error",
|
||||
"Failed to retrieve mounted image information.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (signature.isEmpty() || sig_length == 0) {
|
||||
QMessageBox::information(
|
||||
this, "No Image Mounted",
|
||||
"There is currently no image mounted on the device.");
|
||||
m_mounted_sig.clear();
|
||||
m_mounted_sig_len = 0;
|
||||
displayImages(); // Refresh
|
||||
return;
|
||||
}
|
||||
|
||||
QMessageBox::information(this, "Image Mounted",
|
||||
"A developer disk image is currently "
|
||||
"mounted on the device.");
|
||||
m_mounted_sig =
|
||||
std::string(reinterpret_cast<const char *>(signature.data()),
|
||||
signature.size());
|
||||
m_mounted_sig_len = sig_length;
|
||||
displayImages(); // Refresh
|
||||
},
|
||||
Qt::SingleShotConnection);
|
||||
device->service_manager->get_mounted_image();
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef DEVDISKIMAGESWIDGET_H
|
||||
#define DEVDISKIMAGESWIDGET_H
|
||||
|
||||
#include "devdiskimagehelper.h"
|
||||
#include "iDescriptor-ui.h"
|
||||
#include "iDescriptor.h"
|
||||
#include "qprocessindicator.h"
|
||||
|
||||
+10
-132
@@ -321,9 +321,9 @@ bool DevDiskManager::isImageDownloaded(const QString &version,
|
||||
return QFile::exists(dmgPath) && QFile::exists(sigPath);
|
||||
}
|
||||
|
||||
bool DevDiskManager::downloadCompatibleImage(
|
||||
QString DevDiskManager::downloadCompatibleImage(
|
||||
const std::shared_ptr<iDescriptorDevice> device,
|
||||
std::function<void(bool)> callback)
|
||||
std::function<void(bool, const QString &)> callback)
|
||||
{
|
||||
QString path = SettingsManager::sharedInstance()->mkDevDiskImgPath();
|
||||
unsigned int deviceMajorVersion =
|
||||
@@ -338,8 +338,8 @@ bool DevDiskManager::downloadCompatibleImage(
|
||||
if (images.isEmpty()) {
|
||||
qDebug() << "No images found for device version:" << deviceMajorVersion
|
||||
<< "." << deviceMinorVersion;
|
||||
callback(false);
|
||||
return false;
|
||||
callback(false, "");
|
||||
return "";
|
||||
}
|
||||
|
||||
for (const ImageInfo &info : images) {
|
||||
@@ -348,8 +348,8 @@ bool DevDiskManager::downloadCompatibleImage(
|
||||
continue;
|
||||
}
|
||||
if (info.isDownloaded) {
|
||||
callback(true);
|
||||
return true;
|
||||
callback(true, info.version);
|
||||
return info.version;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +364,7 @@ bool DevDiskManager::downloadCompatibleImage(
|
||||
callback](const QString &finishedVersion, bool success,
|
||||
const QString &errorMessage) {
|
||||
if (finishedVersion == versionToDownload) {
|
||||
callback(success);
|
||||
callback(success, versionToDownload);
|
||||
}
|
||||
},
|
||||
Qt::SingleShotConnection);
|
||||
@@ -392,129 +392,13 @@ bool DevDiskManager::downloadCompatibleImage(
|
||||
|
||||
m_activeDownloads[downloadItem->dmgReply] = downloadItem;
|
||||
m_activeDownloads[downloadItem->sigReply] = downloadItem;
|
||||
return true; // Indicate that the async operation has started
|
||||
return versionToDownload;
|
||||
}
|
||||
}
|
||||
|
||||
// qDebug() << "No compatible image found to mount on device:"
|
||||
// << device->udid.c_str();
|
||||
qDebug() << "No compatible image found to mount on device:" << device->udid;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: wire this up properly
|
||||
bool DevDiskManager::mountCompatibleImage(const iDescriptorDevice *device)
|
||||
{
|
||||
QString path = SettingsManager::sharedInstance()->mkDevDiskImgPath();
|
||||
|
||||
QList<ImageInfo> images =
|
||||
parseImageList(path, device->deviceInfo.parsedDeviceVersion.major,
|
||||
device->deviceInfo.parsedDeviceVersion.minor, "", 0);
|
||||
|
||||
return false;
|
||||
// 1. Try to mount an already downloaded compatible image
|
||||
// for (const ImageInfo &info : images) {
|
||||
// if (info.compatibility != ImageCompatibility::Compatible &&
|
||||
// info.compatibility != ImageCompatibility::MaybeCompatible) {
|
||||
// continue;
|
||||
// }
|
||||
// if (info.isDownloaded) {
|
||||
// qDebug() << "There is a compatible image already downloaded:"
|
||||
// << info.version;
|
||||
// qDebug() << "Attempting to mount image version" << info.version
|
||||
// << "on device:" << device->udid.c_str();
|
||||
// if (MOBILE_IMAGE_MOUNTER_E_SUCCESS ==
|
||||
// mountImage(info.version, device)) {
|
||||
// qDebug() << "Mounted existing image version" << info.version
|
||||
// << "on device:" << device->udid.c_str();
|
||||
// return true;
|
||||
// } else {
|
||||
// qDebug() << "Failed to mount existing image version"
|
||||
// << info.version
|
||||
// << "on device:" << device->udid.c_str();
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 2. If none are downloaded, download the newest compatible one
|
||||
// for (const ImageInfo &info : images) {
|
||||
// if (info.compatibility == ImageCompatibility::Compatible ||
|
||||
// info.compatibility == ImageCompatibility::MaybeCompatible) {
|
||||
// const QString versionToDownload = info.version;
|
||||
// qDebug()
|
||||
// << "No compatible image found locally. Downloading version:"
|
||||
// << versionToDownload;
|
||||
|
||||
// connect(
|
||||
// this, &DevDiskManager::imageDownloadFinished, this,
|
||||
// [this, device, path,
|
||||
// versionToDownload](const QString &finishedVersion,
|
||||
// bool success, const QString
|
||||
// &errorMessage) {
|
||||
// if (success && finishedVersion == versionToDownload) {
|
||||
// qDebug() << "Download finished for" <<
|
||||
// finishedVersion
|
||||
// << ". Now attempting to mount.";
|
||||
// mountImage(finishedVersion, device);
|
||||
// } else if (!success) {
|
||||
// qDebug() << "Failed to download" << finishedVersion
|
||||
// << ":" << errorMessage;
|
||||
// }
|
||||
// },
|
||||
// Qt::SingleShotConnection);
|
||||
|
||||
// // Start the download
|
||||
// QPair<QNetworkReply *, QNetworkReply *> replies =
|
||||
// downloadImage(versionToDownload);
|
||||
// auto *downloadItem = new DownloadItem();
|
||||
// downloadItem->version = versionToDownload;
|
||||
// downloadItem->downloadPath = path;
|
||||
// downloadItem->dmgReply = replies.first;
|
||||
// downloadItem->sigReply = replies.second;
|
||||
|
||||
// connect(downloadItem->dmgReply, &QNetworkReply::downloadProgress,
|
||||
// this, &DevDiskManager::onDownloadProgress);
|
||||
// connect(downloadItem->dmgReply, &QNetworkReply::finished, this,
|
||||
// &DevDiskManager::onFileDownloadFinished);
|
||||
// connect(downloadItem->sigReply, &QNetworkReply::downloadProgress,
|
||||
// this, &DevDiskManager::onDownloadProgress);
|
||||
// connect(downloadItem->sigReply, &QNetworkReply::finished, this,
|
||||
// &DevDiskManager::onFileDownloadFinished);
|
||||
|
||||
// m_activeDownloads[downloadItem->dmgReply] = downloadItem;
|
||||
// m_activeDownloads[downloadItem->sigReply] = downloadItem;
|
||||
// return true; // Indicate that the async operation has started
|
||||
// }
|
||||
// }
|
||||
|
||||
// qDebug() << "No compatible image found to mount on device:"
|
||||
// << device->udid.c_str();
|
||||
|
||||
// return false;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
bool DevDiskManager::mountImage(const QString &version,
|
||||
const iDescriptorDevice *device)
|
||||
{
|
||||
const QString downloadPath =
|
||||
SettingsManager::sharedInstance()->devdiskimgpath();
|
||||
if (!isImageDownloaded(version, downloadPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString versionPath = QDir(downloadPath).filePath(version);
|
||||
return false;
|
||||
// return mount_dev_image(device,
|
||||
// QDir(versionPath)
|
||||
// .filePath("DeveloperDiskImage.dmg")
|
||||
// .toUtf8()
|
||||
// .constData(),
|
||||
// QDir(versionPath)
|
||||
// .filePath("DeveloperDiskImage.dmg.signature")
|
||||
// .toUtf8()
|
||||
// .constData());
|
||||
return "";
|
||||
}
|
||||
|
||||
std::pair<QString, QString>
|
||||
@@ -606,12 +490,6 @@ void DevDiskManager::onFileDownloadFinished()
|
||||
}
|
||||
}
|
||||
|
||||
bool DevDiskManager::unmountImage()
|
||||
{
|
||||
// TODO: Implement
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DevDiskManager::compareSignatures(const char *signature_file_path,
|
||||
const char *mounted_sig,
|
||||
uint64_t mounted_sig_len)
|
||||
|
||||
@@ -59,9 +59,9 @@ public:
|
||||
|
||||
QByteArray getImageListData() const { return m_imageListJsonData; }
|
||||
bool mountCompatibleImage(const iDescriptorDevice *device);
|
||||
bool
|
||||
downloadCompatibleImage(const std::shared_ptr<iDescriptorDevice> device,
|
||||
std::function<void(bool)> callback);
|
||||
QString downloadCompatibleImage(
|
||||
const std::shared_ptr<iDescriptorDevice> device,
|
||||
std::function<void(bool, const QString &version)> callback);
|
||||
|
||||
signals:
|
||||
void imageListFetched(bool success,
|
||||
|
||||
Reference in New Issue
Block a user