diff --git a/.gitmodules b/.gitmodules
index 1e3396f..13c8d2e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -10,3 +10,6 @@
[submodule "lib/win-ifuse"]
path = lib/win-ifuse
url = https://github.com/uncor3/win-ifuse.git
+[submodule "lib/idevice-rs"]
+ path = lib/idevice-rs
+ url = https://github.com/jkcoxson/idevice.git
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index 0b6e02f..cc09ba3 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -1,25 +1,27 @@
{
- "configurations": [
- {
- "name": "Linux",
- "includePath": [
- "${workspaceFolder}/**",
- "/usr/include/qt/**",
- "/usr/local/opt/qt/**",
- "${workspaceFolder}/build/Desktop-Debug/iDescriptor_autogen/include",
- "${workspaceFolder}/build/Desktop-Debug/src/lib/**",
- "/usr/local/include/**",
- "/usr/include/qt6/**",
- "/usr/include/qt6/QtBluetooth/**",
- "${workspaceFolder}/lib/zupdater/src",
- "/usr/include/qt6/QtConcurrent"
- ],
- "defines": [],
- "compilerPath": "/usr/bin/gcc",
- "cStandard": "c17",
- "cppStandard": "gnu++17",
- "intelliSenseMode": "linux-gcc-x64"
- }
- ],
- "version": 4
-}
\ No newline at end of file
+ "configurations": [
+ {
+ "name": "Linux",
+ "includePath": [
+ "${workspaceFolder}/**",
+ "/usr/include/qt/**",
+ "/usr/local/opt/qt/**",
+ "${workspaceFolder}/build/Desktop-Debug/iDescriptor_autogen/include",
+ "${workspaceFolder}/build/Desktop-Debug/src/lib/**",
+ "/usr/local/include/**",
+ "/usr/include/qt6/**",
+ "/usr/include/qt6/QtBluetooth/**",
+ "${workspaceFolder}/lib/zupdater/src",
+ "/usr/include/qt6/QtConcurrent",
+ "/usr/include/qt6",
+ "${workspaceFolder}/build/Desktop-Release/iDescriptor_autogen/include"
+ ],
+ "defines": ["APP_VERSION=\"\""],
+ "compilerPath": "/usr/bin/gcc",
+ "cStandard": "c17",
+ "cppStandard": "gnu++17",
+ "intelliSenseMode": "linux-gcc-x64"
+ }
+ ],
+ "version": 4
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 4ec39cc..d6a8410 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -202,6 +202,10 @@
"qimage": "cpp",
"qabstractbutton": "cpp",
"qtnetwork": "cpp",
- "qtcore": "cpp"
+ "qtcore": "cpp",
+ "csetjmp": "cpp",
+ "qthread": "cpp",
+ "qregularexpression": "cpp",
+ "qnetworkaccessmanager": "cpp"
}
}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1d2d993..7c794b5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,43 +19,42 @@ if (APPLE)
endif()
# Platform-specific paths for libraries built from source
-if(WIN32)
- include_directories("C:/msys64/mingw64/include")
- link_directories("C:/msys64/mingw64/lib")
- set(PKG_CONFIG_EXECUTABLE "C:/msys64/mingw64/bin/pkg-config.exe")
- list(APPEND CMAKE_PREFIX_PATH "C:/lxqt")
- set(CUSTOM_LIB_PATH "C:/msys64/mingw64/lib")
- set(CUSTOM_INCLUDE_PATH "C:/msys64/mingw64/include")
- set(CUSTOM_PKGCONFIG_PATH "C:/msys64/mingw64/lib/pkgconfig")
- set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH};$ENV{PKG_CONFIG_PATH}")
-elseif(APPLE)
- set(CUSTOM_LIB_PATH "/usr/local/lib")
- set(CUSTOM_INCLUDE_PATH "/usr/local/include")
- set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig")
- set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH}:$ENV{PKG_CONFIG_PATH}")
-else ()
- set(CUSTOM_LIB_PATH "/usr/local/lib")
- set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig")
- set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CUSTOM_PKGCONFIG_PATH}")
-endif()
+# if(WIN32)
+# include_directories("C:/msys64/mingw64/include")
+# link_directories("C:/msys64/mingw64/lib")
+# set(PKG_CONFIG_EXECUTABLE "C:/msys64/mingw64/bin/pkg-config.exe")
+# list(APPEND CMAKE_PREFIX_PATH "C:/lxqt")
+# set(CUSTOM_LIB_PATH "C:/msys64/mingw64/lib")
+# set(CUSTOM_INCLUDE_PATH "C:/msys64/mingw64/include")
+# set(CUSTOM_PKGCONFIG_PATH "C:/msys64/mingw64/lib/pkgconfig")
+# set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH};$ENV{PKG_CONFIG_PATH}")
+# elseif(APPLE)
+# set(CUSTOM_LIB_PATH "/usr/local/lib")
+# # Remove the problematic include path that's causing conflicts
+# # set(CUSTOM_INCLUDE_PATH "/usr/local/include")
+# set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig")
+# set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH}:$ENV{PKG_CONFIG_PATH}")
+# else ()
+# set(CUSTOM_LIB_PATH "/usr/local/lib")
+# set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig")
+# set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CUSTOM_PKGCONFIG_PATH}")
+# endif()
-include_directories(${CUSTOM_INCLUDE_PATH})
+# foreach(_ IN LISTS CMAKE_PREFIX_PATH)
+# list(APPEND _qt_pkg_dirs
+# "${_}/lib/pkgconfig"
+# "${_}/lib64/pkgconfig"
+# "${_}/lib64/qt/pkgconfig"
+# "${_}/lib/qt/pkgconfig"
+# )
+# endforeach()
-foreach(_ IN LISTS CMAKE_PREFIX_PATH)
- list(APPEND _qt_pkg_dirs
- "${_}/lib/pkgconfig"
- "${_}/lib64/pkgconfig"
- "${_}/lib64/qt/pkgconfig"
- "${_}/lib/qt/pkgconfig"
- )
-endforeach()
-
-
-list(APPEND _qt_pkg_dirs ${CUSTOM_PKGCONFIG_PATH})
+# list(APPEND _qt_pkg_dirs ${CUSTOM_PKGCONFIG_PATH})
find_package(PkgConfig REQUIRED)
find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia MultimediaWidgets Network QuickControls2 SerialPort Positioning Location QuickWidgets)
+find_package(Qt6 REQUIRED COMPONENTS Core)
# Add QTermWidget
# Prefer CMake-native qtermwidget6, fallback to pkg-config if needed
@@ -84,36 +83,86 @@ if(WIN32)
message(STATUS "Found Qt bin directory: ${QT_BIN_PATH}")
endif()
-# Define library search behavior based on platform
-if(LINUX)
- # On Linux (AUR builds), let CMake search default system paths first.
- # The custom path /usr/local/lib will be checked if it's in the default search paths.
- set(CUSTOM_FIND_LIB_ARGS "")
-else()
- # On other platforms, only search the custom path for our specific libraries.
- set(CUSTOM_FIND_LIB_ARGS
- PATHS ${CUSTOM_LIB_PATH}
- NO_DEFAULT_PATH
+#------------- IDEVICE-RS INTEGRATION -------------
+
+find_program(CARGO_EXECUTABLE cargo REQUIRED)
+message(STATUS "Using idevice-rs Rust implementation")
+
+set(IDEVICE_RS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/idevice-rs)
+set(IDEVICE_RS_LIB_PATH ${IDEVICE_RS_SOURCE_DIR}/target/release/libidevice_ffi.a)
+
+# This command builds the Rust library and declares its output file.
+# Any target that uses this output file will automatically depend on this command.
+add_custom_command(
+ OUTPUT ${IDEVICE_RS_LIB_PATH}
+ COMMAND ${CARGO_EXECUTABLE} build --release --manifest-path ${IDEVICE_RS_SOURCE_DIR}/Cargo.toml
+ WORKING_DIRECTORY ${IDEVICE_RS_SOURCE_DIR}
+ COMMENT "Building idevice-rs FFI library"
+ VERBATIM
+)
+
+# This custom target provides a name to build the Rust library explicitly.
+# It depends on the output file, ensuring the custom command is run.
+add_custom_target(idevice_rs_build DEPENDS ${IDEVICE_RS_LIB_PATH})
+
+# Create an imported target for the Rust static library
+add_library(idevice_ffi STATIC IMPORTED GLOBAL)
+set_target_properties(idevice_ffi PROPERTIES
+ IMPORTED_LOCATION "${IDEVICE_RS_LIB_PATH}"
+)
+
+# ---- Build the idevice-rs C++ wrapper library ------------------------------
+set(IDEVICE_CPP_SRC_DIR ${IDEVICE_RS_SOURCE_DIR}/cpp/src)
+set(IDEVICE_CPP_INCLUDE_DIR ${IDEVICE_RS_SOURCE_DIR}/cpp/include)
+set(IDEVICE_FFI_INCLUDE_DIR ${IDEVICE_RS_SOURCE_DIR}/ffi)
+set(PLIST_CPP_INCLUDE_DIR ${IDEVICE_RS_SOURCE_DIR}/plist_ffi/cpp/include)
+set(PLIST_CPP_SRC_DIR ${IDEVICE_RS_SOURCE_DIR}/plist_ffi/cpp/src)
+
+# Collect C++ sources for the wrapper library
+file(GLOB_RECURSE IDEVICE_CPP_SOURCES
+ "${IDEVICE_CPP_SRC_DIR}/*.cpp"
+)
+file(GLOB PLIST_CPP_SOURCES
+ "${PLIST_CPP_SRC_DIR}/*.cpp"
+)
+
+add_library(idevice_cpp STATIC ${IDEVICE_CPP_SOURCES} ${PLIST_CPP_SOURCES})
+
+target_include_directories(idevice_cpp PUBLIC
+ ${IDEVICE_CPP_INCLUDE_DIR}
+ ${PLIST_CPP_INCLUDE_DIR}
+ PRIVATE
+ ${IDEVICE_FFI_INCLUDE_DIR}
+)
+
+# Link idevice_cpp to idevice_ffi and add platform-specific dependencies
+find_package(Threads REQUIRED)
+target_link_libraries(idevice_cpp PUBLIC idevice_ffi Threads::Threads)
+
+if (UNIX AND NOT APPLE)
+ pkg_check_modules(UDEV REQUIRED IMPORTED_TARGET udev)
+ target_link_libraries(idevice_cpp PUBLIC PkgConfig::UDEV dl m)
+elseif(APPLE)
+ find_library(COREFOUNDATION_FRAMEWORK CoreFoundation REQUIRED)
+ find_library(IOKIT_FRAMEWORK IOKit REQUIRED)
+ target_link_libraries(idevice_cpp PUBLIC
+ ${COREFOUNDATION_FRAMEWORK}
+ ${IOKIT_FRAMEWORK}
+ "-framework Security"
+ "-framework SystemConfiguration"
+ "-framework CoreServices"
+ "-framework CFNetwork"
)
+elseif(WIN32)
+ target_link_libraries(idevice_cpp PUBLIC ws2_32 userenv.lib ntdll bcrypt)
endif()
-find_library(IMOBILEDEVICE_LIBRARY
- NAMES imobiledevice-1.0
- ${CUSTOM_FIND_LIB_ARGS}
- REQUIRED
-)
+# Set up variables for linking and includes for the main iDescriptor target
+set(IDEVICE_IMPLEMENTATION_LIBS idevice_cpp)
+# The C header file generated by cbindgen lives here
+set(IDEVICE_IMPLEMENTATION_INCLUDES ${IDEVICE_RS_SOURCE_DIR}/ffi/include)
-find_library(IMOBILEDEVICE_GLUE_LIBRARY
- NAMES imobiledevice-glue-1.0
- ${CUSTOM_FIND_LIB_ARGS}
- REQUIRED
-)
-
-find_library(TATSU_LIBRARY
- NAMES tatsu
- ${CUSTOM_FIND_LIB_ARGS}
- REQUIRED
-)
+#--------------------------------------------------------------------------------
# Add QR code generation library
pkg_check_modules(QRENCODE REQUIRED IMPORTED_TARGET libqrencode)
@@ -126,36 +175,21 @@ pkg_check_modules(AVCODEC REQUIRED IMPORTED_TARGET libavcodec)
pkg_check_modules(AVUTIL REQUIRED IMPORTED_TARGET libavutil)
pkg_check_modules(SWSCALE REQUIRED IMPORTED_TARGET libswscale)
-if(ENABLE_RECOVERY_DEVICE_SUPPORT)
- find_library(IRECOVERY_LIBRARY
- NAMES irecovery-1.0
- PATHS ${CUSTOM_LIB_PATH}
- NO_DEFAULT_PATH
- )
- if(IRECOVERY_LIBRARY)
- message(STATUS "Building with recovery device support enabled")
- else()
- message(WARNING "libirecovery not found. Recovery device support will be disabled. This is to be expected if you are installing from Arch AUR.")
- set(ENABLE_RECOVERY_DEVICE_SUPPORT OFF)
- endif()
-else()
- message(STATUS "Recovery device support disabled")
-endif()
-
-find_library(USBMUXD_LIBRARY
- NAMES usbmuxd-2.0
- ${CUSTOM_FIND_LIB_ARGS}
- REQUIRED
-)
-
-if(WIN32)
- # On MSYS2, these are found in the standard mingw64 prefix
- find_library(SSL_LIBRARY NAMES ssl PATHS C:/msys64/mingw64/lib REQUIRED)
- find_library(CRYPTO_LIBRARY NAMES crypto PATHS C:/msys64/mingw64/lib REQUIRED)
-else()
- find_library(SSL_LIBRARY NAMES ssl REQUIRED)
- find_library(CRYPTO_LIBRARY NAMES crypto REQUIRED)
-endif()
+# if(ENABLE_RECOVERY_DEVICE_SUPPORT)
+# find_library(IRECOVERY_LIBRARY
+# NAMES irecovery-1.0
+# PATHS ${CUSTOM_LIB_PATH}
+# NO_DEFAULT_PATH
+# )
+# if(IRECOVERY_LIBRARY)
+# message(STATUS "Building with recovery device support enabled")
+# else()
+# message(WARNING "libirecovery not found. Recovery device support will be disabled. This is to be expected if you are installing from Arch AUR.")
+# set(ENABLE_RECOVERY_DEVICE_SUPPORT OFF)
+# endif()
+# else()
+# message(STATUS "Recovery device support disabled")
+# endif()
# Add libssh for SSH connections
pkg_check_modules(SSH REQUIRED IMPORTED_TARGET libssh)
@@ -168,15 +202,73 @@ endif()
pkg_check_modules(PUGIXML REQUIRED IMPORTED_TARGET pugixml)
-pkg_check_modules(USB REQUIRED IMPORTED_TARGET libusb-1.0)
-pkg_check_modules(PLIST REQUIRED IMPORTED_TARGET libplist-2.0)
file(GLOB PROJECT_SOURCES
-src/*.cpp
-src/core/helpers/*.cpp
-src/core/services/*.cpp
-src/*.h
+# src/*.cpp
+# src/core/helpers/*.cpp
+# src/core/services/*.cpp
+# src/*.h
+src/mainwindow.cpp
+src/mainwindow.h
+src/devicemonitor.h
+src/main.cpp
+src/core/services/init_device.cpp
+src/core/services/get_battery_info.cpp
+src/core/services/detect_jailbroken.cpp
+src/appcontext.cpp
+src/appcontext.h
+src/devicedatabase.cpp
+src/devicedatabase.h
+src/core/helpers/compare_product_type.cpp
+src/welcomewidget.cpp
+src/welcomewidget.h
+src/ztabwidget.cpp
+src/ztabwidget.h
+src/devicemanagerwidget.cpp
+src/devicemanagerwidget.h
+src/responsiveqlabel.cpp
+src/responsiveqlabel.h
+src/devicesidebarwidget.cpp
+src/devicesidebarwidget.h
+src/devicemenuwidget.cpp
+src/devicemenuwidget.h
+src/deviceinfowidget.cpp
+src/deviceinfowidget.h
+src/batterywidget.cpp
+src/batterywidget.h
+src/diskusagewidget.cpp
+src/diskusagewidget.h
+# src/deviceimagewidget.cpp
+# src/deviceimagewidget.h
+src/iDescriptor-ui.h
+src/infolabel.cpp
+src/infolabel.h
+src/privateinfolabel.cpp
+src/privateinfolabel.h
+src/qprocessindicator.cpp
+src/qprocessindicator.h
+src/diagnosewidget.cpp
+src/diagnosewidget.h
+src/core/services/get-device-info.cpp
+src/deviceimagewidget.cpp
+src/deviceimagewidget.h
+src/settingsmanager.cpp
+src/settingsmanager.h
+# src/fileexplorerwidget.cpp
+# src/fileexplorerwidget.h
+src/settingswidget.cpp
+src/settingswidget.h
+src/ifusemanager.cpp
+src/ifusemanager.h
+src/ifusediskunmountbutton.cpp
+src/ifusediskunmountbutton.h
+src/core/services/get_battery_info.cpp
+src/networkdeviceswidget.cpp
+src/core/services/avahi/avahi_service.h
+src/core/services/avahi/avahi_service.cpp
+src/networkdevicemanager.cpp
+src/networkdevicemanager.h
src/*.ui
resources.qrc
)
@@ -199,12 +291,12 @@ if (WIN32)
list(APPEND PROJECT_SOURCES ${WINDOWS_PLATFORM_SOURCES})
endif()
-if(LINUX)
- list(APPEND PROJECT_SOURCES
- src/core/services/avahi/avahi_service.cpp
- src/core/services/avahi/avahi_service.h
- )
-endif()
+# if(LINUX)
+# list(APPEND PROJECT_SOURCES
+# src/core/services/avahi/avahi_service.cpp
+# src/core/services/avahi/avahi_service.h
+# )
+# endif()
if (NOT ENABLE_RECOVERY_DEVICE_SUPPORT)
list(REMOVE_ITEM PROJECT_SOURCES
@@ -253,6 +345,9 @@ else()
)
endif()
+# Make sure idevice_cpp depends on the Rust library being built
+add_dependencies(idevice_cpp idevice_rs_build)
+
target_link_libraries(iDescriptor PRIVATE
Qt6::Widgets
Qt6::Multimedia
@@ -264,17 +359,17 @@ target_link_libraries(iDescriptor PRIVATE
Qt6::Positioning
Qt6::QuickWidgets
Qt6::QuickControls2
- ${IMOBILEDEVICE_LIBRARY}
- ${IMOBILEDEVICE_GLUE_LIBRARY}
- ${TATSU_LIBRARY}
- ${SSL_LIBRARY}
- ${CRYPTO_LIBRARY}
+ # ${IMOBILEDEVICE_LIBRARY}
+ # ${IMOBILEDEVICE_GLUE_LIBRARY}
+ # ${TATSU_LIBRARY}
+ # ${SSL_LIBRARY}
+ # ${CRYPTO_LIBRARY}
PkgConfig::SSH
${SSH_LIBRARY}
- ${USBMUXD_LIBRARY}
+ # ${USBMUXD_LIBRARY}
PkgConfig::PUGIXML
- PkgConfig::USB
- PkgConfig::PLIST
+ # PkgConfig::USB
+ # PkgConfig::PLIST
PkgConfig::QRENCODE
qtermwidget6
PkgConfig::HEIF
@@ -286,17 +381,28 @@ target_link_libraries(iDescriptor PRIVATE
airplay
ipatool-go
ZUpdater
+ ${IDEVICE_IMPLEMENTATION_LIBS}
)
-# Conditionally link libirecovery
-if(ENABLE_RECOVERY_DEVICE_SUPPORT)
- target_link_libraries(iDescriptor PRIVATE ${IRECOVERY_LIBRARY})
-endif()
+# # Conditionally link libirecovery
+# if(ENABLE_RECOVERY_DEVICE_SUPPORT)
+# target_link_libraries(iDescriptor PRIVATE ${IRECOVERY_LIBRARY})
+# endif()
target_include_directories(iDescriptor PRIVATE
+ # Put idevice-rs includes FIRST
+ ${IDEVICE_CPP_INCLUDE_DIR}
+ ${IDEVICE_FFI_INCLUDE_DIR}
+ ${PLIST_CPP_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/lib/zupdater/src
+ # System includes last
+ ${IDEVICE_IMPLEMENTATION_INCLUDES}
)
+
+
+target_include_directories(iDescriptor PRIVATE ${IDEVICE_IMPLEMENTATION_INCLUDES})
+
if(APPLE)
find_library(CORE_SERVICES_FRAMEWORK CoreServices REQUIRED)
target_link_libraries(iDescriptor PRIVATE
@@ -323,6 +429,7 @@ if(APPLE)
${SECURITY_FRAMEWORK}
${COREFOUNDATION_FRAMEWORK}
)
+target_link_libraries(iDescriptor PRIVATE Qt6::Core)
endif()
# Add compile definition for source directory
@@ -368,7 +475,7 @@ if (UNIX AND NOT APPLE)
)
endif()
# Add install rules for the project
-include(GNUInstallDirs)
+# include(GNUInstallDirs)
# Install the main executable
install(TARGETS iDescriptor
diff --git a/README.md b/README.md
index 660092c..f8cb09b 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,9 @@
+# THIS BRANCH IS UNDER DEVELOPMENT
+
+## Migrating to new backend -> https://github.com/jkcoxson/idevice
+
+## Only builds on Linux for now
+

@@ -58,9 +64,10 @@
- **Installer (.msi)**: Download and run the installer. Recommended for most users.
- **Portable (.zip)**: Extract and run `iDescriptor.exe`. No installation required.
- **Choco** :
+
```bash
choco install idescriptor --version=0.1.0
- ```
+```
#### macOS
@@ -72,11 +79,13 @@ Open the `.dmg` and drag iDescriptor to Applications.
#### Linux
- **AppImage**: Download, unzip, and run.
-- **Arch Linux**: Install from AUR:
+- **Arch Linux**: Install from AUR:
+
```bash
sudo pacman -Syu
yay -S idescriptor-git
```
+
make sure to do "sudo pacman -Syu" otherwise it's not going to find libimobiledevice>=1.4.0
@@ -93,7 +102,7 @@ make sure to do "sudo pacman -Syu" otherwise it's not going to find libimobilede
| Feature | Status | Notes |
| --------------------------- | -------------------- | --------------------------------------------- |
| USB Connection | ✅ Implemented | Fully supported on Windows, macOS, and Linux. |
-| Wireless Connection (Wi‑Fi) | ⚠️ To be implemented | - |
+| Wireless Connection (Wi‑Fi) | ⚠️ Under development | - |
### Tools
@@ -224,9 +233,9 @@ You might get this pop-up on any platform this is because this app uses secure b
## Become a Sponsor
-Please support us at
-
-
+Please support us at
+
+
## Thanks
diff --git a/lib/idevice-rs b/lib/idevice-rs
new file mode 160000
index 0000000..5f1e039
--- /dev/null
+++ b/lib/idevice-rs
@@ -0,0 +1 @@
+Subproject commit 5f1e03911f0819ceacd366f76f961be407bec2b6
diff --git a/src/afcexplorerwidget.cpp b/src/afcexplorerwidget.cpp
index df98b72..b979996 100644
--- a/src/afcexplorerwidget.cpp
+++ b/src/afcexplorerwidget.cpp
@@ -43,8 +43,6 @@
#include
#include
#include
-#include
-#include
AfcExplorerWidget::AfcExplorerWidget(iDescriptorDevice *device, bool favEnabled,
afc_client_t afcClient, QString root,
diff --git a/src/afcexplorerwidget.h b/src/afcexplorerwidget.h
index 7c0e8e9..7c7362e 100644
--- a/src/afcexplorerwidget.h
+++ b/src/afcexplorerwidget.h
@@ -37,7 +37,6 @@
#include
#include
#include
-#include
class ExportManager;
class ExportProgressDialog;
@@ -89,7 +88,7 @@ private:
ZIconWidget *m_enterButton;
iDescriptorDevice *m_device;
bool m_favEnabled;
- afc_client_t m_afc;
+ AfcClientHandle *m_afc;
QString m_errorMessage;
QString m_root;
diff --git a/src/appcontext.cpp b/src/appcontext.cpp
index e7b9ab6..25b71b7 100644
--- a/src/appcontext.cpp
+++ b/src/appcontext.cpp
@@ -18,9 +18,11 @@
*/
#include "appcontext.h"
+#include "devicemonitor.h"
#include "iDescriptor.h"
#include "mainwindow.h"
-#include "settingsmanager.h"
+// #include "settingsmanager.h"
+#include "networkdevicemanager.h"
#include
#include
#include
@@ -37,64 +39,191 @@ AppContext *AppContext::sharedInstance()
and does not reconnect them until the user plugs them
back in, even if they are still connected
*/
-AppContext::AppContext(QObject *parent) : QObject{parent} {}
+AppContext::AppContext(QObject *parent) : QObject{parent}
+{
-void AppContext::addDevice(QString udid, idevice_connection_type conn_type,
- AddType addType)
+ // FIXME: windows and macOS support later
+ QDir lockdowndir("/var/lib/lockdown");
+ if (!lockdowndir.exists()) {
+ return;
+ }
+
+ // Load cached pairing files
+ QStringList pairingFiles =
+ lockdowndir.entryList(QStringList() << "*.plist", QDir::Files);
+
+ qDebug() << "Parsing cached pairing files in /var/lib/lockdown:";
+ for (const QString &fileName : pairingFiles) {
+ plist_t fileData = nullptr;
+ plist_read_from_file(
+ lockdowndir.filePath(fileName).toUtf8().constData(), &fileData,
+ NULL);
+
+ if (!fileData) {
+ continue;
+ }
+ plist_print(fileData);
+ const std::string wifiMacAddress =
+ PlistNavigator(fileData)["WiFiMACAddress"].getString();
+ plist_free(fileData);
+ qDebug() << "Found pairing file for MAC"
+ << QString::fromStdString(wifiMacAddress);
+ bool isCompatible = !wifiMacAddress.empty();
+ // TODO: !important invalidate old pairing files
+ // libimobiledevice does not append WIFIMACAddress to the pairing file
+ if (!isCompatible) {
+ continue;
+ }
+
+ IdevicePairingFile *pairing_file = nullptr;
+ idevice_pairing_file_read(
+ lockdowndir.filePath(fileName).toUtf8().constData(), &pairing_file);
+ if (pairing_file) {
+ qDebug() << "Caching pairing file for MAC"
+ << QString::fromStdString(wifiMacAddress);
+ m_pairingFileCache[QString::fromStdString(wifiMacAddress)] =
+ pairing_file;
+ }
+ }
+}
+
+void AppContext::addDevice(QString udid,
+ DeviceMonitorThread::IdeviceConnectionType conn_type,
+ AddType addType, QString wifiMacAddress)
{
try {
- iDescriptorInitDeviceResult initResult =
- init_idescriptor_device(udid.toStdString().c_str());
+ iDescriptorInitDeviceResult initResult;
+
+ if (addType == AddType::UpgradeToWireless) {
+ const IdevicePairingFile *pairingFile = getCachedPairingFile(udid);
+ if (!pairingFile) {
+ qDebug() << "Cannot upgrade to wireless, no pairing file for"
+ << udid;
+ return;
+ }
+
+ QList networkDevices =
+ NetworkDeviceManager::sharedInstance()
+ ->m_networkProvider->getNetworkDevices();
+
+ auto it = std::find_if(
+ networkDevices.constBegin(), networkDevices.constEnd(),
+ [wifiMacAddress](const NetworkDevice &device) {
+ return device.macAddress.compare(wifiMacAddress,
+ Qt::CaseInsensitive) == 0;
+ });
+
+ if (it != networkDevices.constEnd()) {
+
+ IdevicePairingFile *pairing_file = nullptr;
+ idevice_pairing_file_read(QString("/var/lib/lockdown/%1.plist")
+ .arg(udid)
+ .toUtf8()
+ .constData(),
+ &pairing_file);
+ initResult =
+ init_idescriptor_device(udid, {it->address, pairing_file});
+ } else {
+ qDebug() << "No network device found with MAC address:"
+ << wifiMacAddress;
+ return;
+ }
+ } else if (addType == AddType::Wireless) {
+ // FIXME: its not udid here its macAddress
+ const IdevicePairingFile *pairingFile = getCachedPairingFile(udid);
+ if (!pairingFile) {
+ qDebug()
+ << "Cannot initialize wireless device, no pairing file for"
+ << udid;
+ return;
+ }
+
+ QList networkDevices =
+ NetworkDeviceManager::sharedInstance()
+ ->m_networkProvider->getNetworkDevices();
+
+ auto it = std::find_if(
+ networkDevices.constBegin(), networkDevices.constEnd(),
+ [wifiMacAddress](const NetworkDevice &device) {
+ return device.macAddress.compare(wifiMacAddress,
+ Qt::CaseInsensitive) == 0;
+ });
+
+ if (it != networkDevices.constEnd()) {
+ initResult =
+ init_idescriptor_device(udid, {it->address, pairingFile});
+ } else {
+ qDebug() << "No network device found with MAC address:"
+ << wifiMacAddress;
+ return;
+ }
+ }
+
+ else {
+
+ initResult = init_idescriptor_device(udid, {nullptr, nullptr});
+ }
qDebug() << "init_idescriptor_device success ?: " << initResult.success;
- qDebug() << "init_idescriptor_device error code: " << initResult.error;
-
+ // qDebug() << "init_idescriptor_device error code: " <<
+ // initResult.error;
if (!initResult.success) {
qDebug() << "Failed to initialize device with UDID: " << udid;
- if (initResult.error == LOCKDOWN_E_PASSWORD_PROTECTED) {
- if (addType == AddType::Regular) {
- m_pendingDevices.append(udid);
- emit devicePasswordProtected(udid);
- emit deviceChange();
- QTimer::singleShot(
- SettingsManager::sharedInstance()->connectionTimeout() *
- 1000,
- this, [this, udid]() {
- if (m_pendingDevices.contains(udid)) {
- qDebug() << "Pairing expired for device UDID: "
- << udid;
- m_pendingDevices.removeAll(udid);
- emit devicePairingExpired(udid);
- emit deviceChange();
- }
- });
- }
- } else if (initResult.error ==
- LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING ||
- initResult.error == LOCKDOWN_E_INVALID_HOST_ID) {
- m_pendingDevices.append(udid);
- emit devicePairPending(udid);
- emit deviceChange();
- QTimer::singleShot(
- SettingsManager::sharedInstance()->connectionTimeout() *
- 1000,
- this, [this, udid]() {
- qDebug()
- << "Pairing timer fired for device UDID: " << udid;
- if (m_pendingDevices.contains(udid)) {
- qDebug()
- << "Pairing expired for device UDID: " << udid;
- m_pendingDevices.removeAll(udid);
- emit devicePairingExpired(udid);
- emit deviceChange();
- }
- });
- } else {
- qDebug() << "Unhandled error for device UDID: " << udid
- << " Error code: " << initResult.error;
- }
return;
}
+ // if (!initResult.success) {
+ // qDebug() << "Failed to initialize device with UDID: " <<
+ // udid; if (initResult.error == LOCKDOWN_E_PASSWORD_PROTECTED)
+ // {
+ // if (addType == AddType::Regular) {
+ // m_pendingDevices.append(udid);
+ // emit devicePasswordProtected(udid);
+ // emit deviceChange();
+ // QTimer::singleShot(
+ // SettingsManager::sharedInstance()->connectionTimeout()
+ // *
+ // 1000,
+ // this, [this, udid]() {
+ // if (m_pendingDevices.contains(udid)) {
+ // qDebug() << "Pairing expired for device
+ // UDID:
+ // "
+ // << udid;
+ // m_pendingDevices.removeAll(udid);
+ // emit devicePairingExpired(udid);
+ // emit deviceChange();
+ // }
+ // });
+ // }
+ // } else if (initResult.error ==
+ // LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING ||
+ // initResult.error == LOCKDOWN_E_INVALID_HOST_ID) {
+ // m_pendingDevices.append(udid);
+ // emit devicePairPending(udid);
+ // emit deviceChange();
+ // QTimer::singleShot(
+ // SettingsManager::sharedInstance()->connectionTimeout()
+ // *
+ // 1000,
+ // this, [this, udid]() {
+ // qDebug()
+ // << "Pairing timer fired for device UDID: " <<
+ // udid;
+ // if (m_pendingDevices.contains(udid)) {
+ // qDebug()
+ // << "Pairing expired for device UDID: " <<
+ // udid;
+ // m_pendingDevices.removeAll(udid);
+ // emit devicePairingExpired(udid);
+ // emit deviceChange();
+ // }
+ // });
+ // } else {
+ // qDebug() << "Unhandled error for device UDID: " << udid
+ // << " Error code: " << initResult.error;
+ // }
+ // return;
+ // }
qDebug() << "Device initialized: " << udid;
iDescriptorDevice *device = new iDescriptorDevice{
@@ -104,17 +233,20 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type,
.deviceInfo = initResult.deviceInfo,
.afcClient = initResult.afcClient,
.afc2Client = initResult.afc2Client,
+ .lockdown = initResult.lockdown,
.mutex = new std::recursive_mutex(),
};
m_devices[device->udid] = device;
if (addType == AddType::Regular) {
- SettingsManager::sharedInstance()->doIfEnabled(
- SettingsManager::Setting::AutoRaiseWindow, []() {
- if (MainWindow *mainWindow = MainWindow::sharedInstance()) {
- mainWindow->raise();
- mainWindow->activateWindow();
- }
- });
+ qDebug() << "Regular device added: " << udid;
+ // SettingsManager::sharedInstance()->doIfEnabled(
+ // SettingsManager::Setting::AutoRaiseWindow, []() {
+ // if (MainWindow *mainWindow =
+ // MainWindow::sharedInstance()) {
+ // mainWindow->raise();
+ // mainWindow->activateWindow();
+ // }
+ // });
emit deviceAdded(device);
emit deviceChange();
@@ -123,7 +255,6 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type,
emit devicePaired(device);
emit deviceChange();
m_pendingDevices.removeAll(udid);
-
} catch (const std::exception &e) {
qDebug() << "Exception in onDeviceAdded: " << e.what();
}
@@ -131,19 +262,19 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type,
int AppContext::getConnectedDeviceCount() const
{
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- return m_devices.size() + m_recoveryDevices.size();
-#else
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // return m_devices.size() + m_recoveryDevices.size();
+ // #else
return m_devices.size();
-#endif
+ // #endif
}
/*
FIXME:
on macOS, sometimes you get wireless disconnects even though we are not
- listening for wireless devices it does not have any to do with us, but it
- still happens so be aware of that
-*/
+ listening for wireless devices it does not have any to do with us, but
+ it still happens so be aware of that
+ */
void AppContext::removeDevice(QString _udid)
{
const std::string udid = _udid.toStdString();
@@ -169,41 +300,41 @@ void AppContext::removeDevice(QString _udid)
iDescriptorDevice *device = m_devices[udid];
m_devices.remove(udid);
- emit deviceRemoved(udid);
+ emit deviceRemoved(udid, device->deviceInfo.wifiMacAddress);
emit deviceChange();
- std::lock_guard lock(*device->mutex);
+ // std::lock_guard lock(*device->mutex);
- if (device->afcClient)
- afc_client_free(device->afcClient);
- if (device->afc2Client)
- afc_client_free(device->afc2Client);
- idevice_free(device->device);
- delete device->mutex;
- delete device;
+ // if (device->afcClient)
+ // afc_client_free(device->afcClient);
+ // if (device->afc2Client)
+ // afc_client_free(device->afc2Client);
+ // idevice_free(device->device);
+ // delete device->mutex;
+ // delete device;
}
#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
void AppContext::removeRecoveryDevice(uint64_t ecid)
{
- if (!m_recoveryDevices.contains(ecid)) {
- qDebug() << "Device with ECID " + QString::number(ecid) +
- " not found. Please report this issue.";
- return;
- }
+ // if (!m_recoveryDevices.contains(ecid)) {
+ // qDebug() << "Device with ECID " + QString::number(ecid) +
+ // " not found. Please report this issue.";
+ // return;
+ // }
- qDebug() << "Removing recovery device with ECID:" << ecid;
+ // qDebug() << "Removing recovery device with ECID:" << ecid;
- // Fix use-after-free: get pointer before removing from map
- iDescriptorRecoveryDevice *deviceInfo = m_recoveryDevices.value(ecid);
- m_recoveryDevices.remove(ecid);
+ // // Fix use-after-free: get pointer before removing from map
+ // iDescriptorRecoveryDevice *deviceInfo =
+ // m_recoveryDevices.value(ecid); m_recoveryDevices.remove(ecid);
- emit recoveryDeviceRemoved(ecid);
- emit deviceChange();
+ // emit recoveryDeviceRemoved(ecid);
+ // emit deviceChange();
- std::lock_guard lock(*deviceInfo->mutex);
- delete deviceInfo->mutex;
- delete deviceInfo;
+ // std::lock_guard lock(*deviceInfo->mutex);
+ // delete deviceInfo->mutex;
+ // delete deviceInfo;
}
#endif
@@ -217,91 +348,121 @@ QList AppContext::getAllDevices()
return m_devices.values();
}
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-QList AppContext::getAllRecoveryDevices()
-{
- return m_recoveryDevices.values();
-}
-#endif
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// QList AppContext::getAllRecoveryDevices()
+// {
+// // return m_recoveryDevices.values();
+// }
+// #endif
// Returns whether there are any devices connected (regular or recovery)
bool AppContext::noDevicesConnected() const
{
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- return (m_devices.isEmpty() && m_recoveryDevices.isEmpty() &&
- m_pendingDevices.isEmpty());
-#else
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // return (m_devices.isEmpty() && m_recoveryDevices.isEmpty() &&
+ // m_pendingDevices.isEmpty());
+ // #else
return (m_devices.isEmpty() && m_pendingDevices.isEmpty());
-#endif
+ // #endif
}
#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
void AppContext::addRecoveryDevice(uint64_t ecid)
{
- iDescriptorInitDeviceResultRecovery res =
- init_idescriptor_recovery_device(ecid);
+ // iDescriptorInitDeviceResultRecovery res =
+ // init_idescriptor_recovery_device(ecid);
- if (!res.success) {
- qDebug() << "Failed to initialize recovery device with ECID: "
- << QString::number(ecid);
- qDebug() << "Error code: " << res.error;
- return;
- }
+ // if (!res.success) {
+ // qDebug() << "Failed to initialize recovery device with ECID: "
+ // << QString::number(ecid);
+ // qDebug() << "Error code: " << res.error;
+ // return;
+ // }
- iDescriptorRecoveryDevice *recoveryDevice = new iDescriptorRecoveryDevice();
- recoveryDevice->ecid = res.deviceInfo.ecid;
- recoveryDevice->mode = res.mode;
- recoveryDevice->cpid = res.deviceInfo.cpid;
- recoveryDevice->bdid = res.deviceInfo.bdid;
- recoveryDevice->displayName = res.displayName;
- recoveryDevice->mutex = new std::recursive_mutex();
+ // iDescriptorRecoveryDevice *recoveryDevice = new
+ // iDescriptorRecoveryDevice(); recoveryDevice->ecid =
+ // res.deviceInfo.ecid; recoveryDevice->mode = res.mode;
+ // recoveryDevice->cpid = res.deviceInfo.cpid;
+ // recoveryDevice->bdid = res.deviceInfo.bdid;
+ // recoveryDevice->displayName = res.displayName;
+ // recoveryDevice->mutex = new std::recursive_mutex();
- m_recoveryDevices[res.deviceInfo.ecid] = recoveryDevice;
- emit recoveryDeviceAdded(recoveryDevice);
- emit deviceChange();
+ // m_recoveryDevices[res.deviceInfo.ecid] = recoveryDevice;
+ // emit recoveryDeviceAdded(recoveryDevice);
+ // emit deviceChange();
}
#endif
AppContext::~AppContext()
{
- for (auto device : m_devices) {
- emit deviceRemoved(device->udid);
- if (device->afcClient)
- afc_client_free(device->afcClient);
- if (device->afc2Client)
- afc_client_free(device->afc2Client);
- idevice_free(device->device);
- delete device->mutex;
- delete device;
- }
+ // for (auto device : m_devices) {
+ // emit deviceRemoved(device->udid);
+ // if (device->afcClient)
+ // afc_client_free(device->afcClient);
+ // if (device->afc2Client)
+ // afc_client_free(device->afc2Client);
+ // idevice_free(device->device);
+ // delete device->mutex;
+ // delete device;
+ // }
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- for (auto recoveryDevice : m_recoveryDevices) {
- emit recoveryDeviceRemoved(recoveryDevice->ecid);
- delete recoveryDevice->mutex;
- delete recoveryDevice;
- }
-#endif
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // for (auto recoveryDevice : m_recoveryDevices) {
+ // emit recoveryDeviceRemoved(recoveryDevice->ecid);
+ // delete recoveryDevice->mutex;
+ // delete recoveryDevice;
+ // }
+ // #endif
}
void AppContext::setCurrentDeviceSelection(const DeviceSelection &selection)
{
- qDebug() << "New selection -"
- << " Type:" << selection.type
- << " UDID:" << QString::fromStdString(selection.udid)
- << " ECID:" << selection.ecid << " Section:" << selection.section;
- if (m_currentSelection.type == selection.type &&
- m_currentSelection.udid == selection.udid &&
- m_currentSelection.ecid == selection.ecid &&
- m_currentSelection.section == selection.section) {
- qDebug() << "setCurrentDeviceSelection: No change in selection";
- return; // No change
- }
- m_currentSelection = selection;
- emit currentDeviceSelectionChanged(m_currentSelection);
+ // qDebug() << "New selection -"
+ // << " Type:" << selection.type
+ // << " UDID:" << QString::fromStdString(selection.udid)
+ // << " ECID:" << selection.ecid << " Section:" <<
+ // selection.section;
+ // if (m_currentSelection.type == selection.type &&
+ // m_currentSelection.udid == selection.udid &&
+ // m_currentSelection.ecid == selection.ecid &&
+ // m_currentSelection.section == selection.section) {
+ // qDebug() << "setCurrentDeviceSelection: No change in selection";
+ // return; // No change
+ // }
+ // m_currentSelection = selection;
+ // emit currentDeviceSelectionChanged(m_currentSelection);
}
const DeviceSelection &AppContext::getCurrentDeviceSelection() const
{
return m_currentSelection;
-}
\ No newline at end of file
+}
+
+const iDescriptorDevice *
+AppContext::getDeviceByMacAddress(const QString &macAddress) const
+{
+ for (const iDescriptorDevice *device : m_devices) {
+ if (device->deviceInfo.wifiMacAddress == macAddress.toStdString()) {
+ return device;
+ }
+ }
+ return nullptr;
+}
+
+void AppContext::cachePairingFile(const QString &udid,
+ IdevicePairingFile *pairingFile)
+{
+ m_pairingFileCache.insert(udid, pairingFile);
+}
+const IdevicePairingFile *
+AppContext::getCachedPairingFile(const QString &udid) const
+{
+ const IdevicePairingFile *pairingFile = nullptr;
+
+ // Retrieve the pairing file from the cache
+ if (m_pairingFileCache.contains(udid)) {
+ pairingFile = m_pairingFileCache.value(udid);
+ }
+
+ return pairingFile;
+}
diff --git a/src/appcontext.h b/src/appcontext.h
index 3ba8c26..c4d5200 100644
--- a/src/appcontext.h
+++ b/src/appcontext.h
@@ -20,6 +20,7 @@
#ifndef APPCONTEXT_H
#define APPCONTEXT_H
+#include "devicemonitor.h"
#include "devicesidebarwidget.h"
#include "iDescriptor.h"
#include
@@ -33,32 +34,38 @@ public:
QList getAllDevices();
explicit AppContext(QObject *parent = nullptr);
bool noDevicesConnected() const;
+ void cachePairingFile(const QString &udid, IdevicePairingFile *pairingFile);
+ const IdevicePairingFile *getCachedPairingFile(const QString &udid) const;
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- QList getAllRecoveryDevices();
-#endif
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // QList getAllRecoveryDevices();
+ // #endif
~AppContext();
int getConnectedDeviceCount() const;
void setCurrentDeviceSelection(const DeviceSelection &selection);
const DeviceSelection &getCurrentDeviceSelection() const;
+ const iDescriptorDevice *
+ getDeviceByMacAddress(const QString &macAddress) const;
private:
QMap m_devices;
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- QMap m_recoveryDevices;
-#endif
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // QMap m_recoveryDevices;
+ // #endif
QStringList m_pendingDevices;
DeviceSelection m_currentSelection = DeviceSelection("");
+ // FIXME: QString can be macAddress or udid - both works fine for now
+ QMap m_pairingFileCache;
signals:
void deviceAdded(iDescriptorDevice *device);
- void deviceRemoved(const std::string &udid);
+ void deviceRemoved(const std::string &udid, const std::string &macAddress);
void devicePaired(iDescriptorDevice *device);
void devicePasswordProtected(const QString &udid);
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- void recoveryDeviceAdded(const iDescriptorRecoveryDevice *deviceInfo);
- void recoveryDeviceRemoved(uint64_t ecid);
-#endif
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // void recoveryDeviceAdded(const iDescriptorRecoveryDevice
+ // *deviceInfo); void recoveryDeviceRemoved(uint64_t ecid);
+ // #endif
void devicePairPending(const QString &udid);
void devicePairingExpired(const QString &udid);
void systemSleepStarting();
@@ -74,8 +81,9 @@ signals:
void currentDeviceSelectionChanged(const DeviceSelection &selection);
public slots:
void removeDevice(QString udid);
- void addDevice(QString udid, idevice_connection_type connType,
- AddType addType);
+ void addDevice(QString udid,
+ DeviceMonitorThread::IdeviceConnectionType connType,
+ AddType addType, QString wifiMacAddress = QString());
#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
void addRecoveryDevice(uint64_t ecid);
void removeRecoveryDevice(uint64_t ecid);
diff --git a/src/core/services/avahi/avahi_service.cpp b/src/core/services/avahi/avahi_service.cpp
index 585061a..dda167c 100644
--- a/src/core/services/avahi/avahi_service.cpp
+++ b/src/core/services/avahi/avahi_service.cpp
@@ -217,9 +217,10 @@ void AvahiService::resolveCallback(
avahi_free(value);
}
}
-
+ device.macAddress = device.name.split('@').first();
qDebug() << "Resolved Apple device:" << device.name << "at"
- << device.address << ":" << device.port;
+ << device.address << ":" << device.port
+ << "MAC:" << device.macAddress;
// Add to our list if not already present
{
diff --git a/src/core/services/detect_jailbroken.cpp b/src/core/services/detect_jailbroken.cpp
index ff41ec9..10c9347 100644
--- a/src/core/services/detect_jailbroken.cpp
+++ b/src/core/services/detect_jailbroken.cpp
@@ -18,7 +18,7 @@
*/
#include "../../iDescriptor.h"
-#include
+
// char *possible_jailbreak_paths[] = {
// "/Applications/Cydia.app",
// "/Library/MobileSubstrate/MobileSubstrate.dylib",
@@ -29,18 +29,15 @@
// };
#include
-bool detect_jailbroken(afc_client_t afc)
+bool detect_jailbroken(AfcClientHandle *afc)
{
char **dirs = NULL;
- if (afc_read_directory(afc, (std::string(POSSIBLE_ROOT) + "bin").c_str(),
- &dirs) == AFC_E_SUCCESS) {
- // if we can loop through the directory, it means we have access to the
- // file system
- for (char **dir = dirs; *dir != nullptr; ++dir) {
- afc_dictionary_free(dirs);
- return true;
- }
+ size_t count = 0;
+ bool res = false;
+ if (!afc_list_directory(afc, (std::string(POSSIBLE_ROOT) + "bin").c_str(),
+ &dirs, &count)) {
+ free(dirs);
}
- afc_dictionary_free(dirs);
- return false;
+
+ return res > 0;
}
\ No newline at end of file
diff --git a/src/core/services/get-device-info.cpp b/src/core/services/get-device-info.cpp
index 2337a35..7c0a029 100644
--- a/src/core/services/get-device-info.cpp
+++ b/src/core/services/get-device-info.cpp
@@ -52,8 +52,8 @@
#include
#endif
-#include
-#include
+#include "../../iDescriptor.h"
+#include
#include
#include
@@ -82,35 +82,41 @@ static const char *domains[] = {
"com.apple.mobile.iTunes", "com.apple.fmip", "com.apple.Accessibility",
NULL};
-plist_t get_device_info(const char *udid, lockdownd_client_t client,
- idevice_t device)
+plist_t get_device_info(const char *udid, LockdowndClientHandle *client)
{
- lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
- idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
+ IdeviceFfiError *err;
plist_t node = NULL;
/* run query and output information */
- if (lockdownd_get_value(client, NULL, NULL, &node) != LOCKDOWN_E_SUCCESS) {
- fprintf(stderr, "ERROR: Could not get value\n");
+ err = lockdownd_get_value(client, NULL, NULL, &node);
+
+ if (err) {
+ qDebug() << "ERROR: Could not get value";
}
plist_t disk_info = nullptr;
uint64_t total_space = 0;
uint64_t free_space = 0;
- if (lockdownd_get_value(client, "com.apple.disk_usage", nullptr,
- &disk_info) == LOCKDOWN_E_SUCCESS) {
+ err = lockdownd_get_value(client, nullptr, "com.apple.disk_usage",
+ &disk_info);
+ qDebug() << "Disk usage fetch error:" << (err ? err->message : "none");
+
+ if (!err) {
+ qDebug() << "Disk Usage Info:";
+ plist_print(disk_info);
+
// merge dict
plist_dict_merge(&node, disk_info);
- plist_free(disk_info);
+ // plist_free(disk_info);
}
return node;
}
-void get_device_info_xml(const char *udid, lockdownd_client_t client,
- idevice_t device, pugi::xml_document &infoXml)
+void get_device_info_xml(const char *udid, LockdowndClientHandle *client,
+ pugi::xml_document &infoXml)
{
- plist_t node = get_device_info(udid, client, device);
+ plist_t node = get_device_info(udid, client);
if (!node)
return;
char *xml_string = nullptr;
diff --git a/src/core/services/get_battery_info.cpp b/src/core/services/get_battery_info.cpp
index 65cd169..18ab2e5 100644
--- a/src/core/services/get_battery_info.cpp
+++ b/src/core/services/get_battery_info.cpp
@@ -20,35 +20,45 @@
#include "../../iDescriptor.h"
#include "plist/plist.h"
#include
-#include
#include
-void get_battery_info(std::string productType, idevice_t idevice,
- bool is_iphone, plist_t &diagnostics)
+// FIXME: return bool
+void get_battery_info(IdeviceProviderHandle *provider, plist_t &diagnostics)
{
- diagnostics_relay_client_t diagnostics_client = nullptr;
- try {
+ // 1. Connect to the diagnostics_relay service using the raw C function.
+ DiagnosticsRelayClientHandle *client_handle = nullptr;
+ IdeviceFfiError *err =
+ ::diagnostics_relay_client_connect(provider, &client_handle);
- if (diagnostics_relay_client_start_service(idevice, &diagnostics_client,
- nullptr) !=
- DIAGNOSTICS_RELAY_E_SUCCESS) {
- qDebug() << "Failed to start diagnostics relay service.";
- return;
- }
+ if (err) {
+ qDebug() << "Failed to create diagnostics relay client:"
+ << err->message;
+ idevice_error_free(err);
+ return;
+ }
- if (diagnostics_relay_query_ioregistry_entry(
- diagnostics_client, nullptr, "IOPMPowerSource", &diagnostics) !=
- DIAGNOSTICS_RELAY_E_SUCCESS &&
- !diagnostics) {
+ // 2. Adopt the raw handle into the C++ RAII wrapper.
+ // The client will now be automatically freed when it goes out of scope.
+ auto diagnostics_client =
+ IdeviceFFI::DiagnosticsRelay::adopt(client_handle);
- qDebug()
- << "Failed to query diagnostics relay for AppleARMPMUCharger.";
- if (diagnostics_client)
- diagnostics_relay_client_free(diagnostics_client);
- }
- } catch (const std::exception &e) {
- if (diagnostics_client)
- diagnostics_relay_client_free(diagnostics_client);
- qDebug() << "Exception in get_battery_info: " << e.what();
+ // 3. Query IORegistry for battery info.
+ auto ioreg_result = diagnostics_client.ioregistry(
+ IdeviceFFI::None, // current_plane
+ IdeviceFFI::None, // entry_name
+ IdeviceFFI::Some(std::string("IOPMPowerSource")) // entry_class
+ );
+
+ if (!ioreg_result.is_ok()) {
+ qDebug() << "Failed to query IORegistry:"
+ << ioreg_result.unwrap_err().message.c_str();
+ return;
+ }
+
+ // 4. Unwrap the result and handle the optional plist.
+ auto plist_opt = std::move(ioreg_result).unwrap();
+ if (plist_opt.is_some()) {
+ // The caller of get_battery_info is responsible for freeing this plist.
+ diagnostics = std::move(plist_opt).unwrap();
}
}
\ No newline at end of file
diff --git a/src/core/services/init_device.cpp b/src/core/services/init_device.cpp
index 0062a21..8ef71bc 100644
--- a/src/core/services/init_device.cpp
+++ b/src/core/services/init_device.cpp
@@ -19,16 +19,19 @@
#include "../../devicedatabase.h"
#include "../../iDescriptor.h"
-#include "../../servicemanager.h"
+// #include "../../servicemanager.h"
+#include "../../appcontext.h"
#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
#include "libirecovery.h"
#endif
#include
-#include
-#include
-#include
#include
+#include
+#include
+#include
+
+#include
std::string safeGetXML(const char *key, pugi::xml_node dict)
{
for (pugi::xml_node child = dict.first_child(); child;
@@ -150,7 +153,8 @@ void parseDeviceBattery(PlistNavigator &ioreg, DeviceInfo &d)
}
DeviceInfo fullDeviceInfo(const pugi::xml_document &doc,
- afc_client_t &afcClient,
+ AfcClientHandle *afcClient,
+ IdeviceProviderHandle *provider,
iDescriptorInitDeviceResult &result)
{
pugi::xml_node dict = doc.child("plist").child("dict");
@@ -194,6 +198,7 @@ DeviceInfo fullDeviceInfo(const pugi::xml_document &doc,
d.bluetoothAddress = safeGet("BluetoothAddress");
d.firmwareVersion = safeGet("FirmwareVersion");
d.productVersion = safeGet("ProductVersion");
+ d.wifiMacAddress = safeGet("WiFiAddress");
QString q_version = QString::fromStdString(d.productVersion);
QStringList parts = q_version.split('.');
@@ -206,17 +211,25 @@ DeviceInfo fullDeviceInfo(const pugi::xml_document &doc,
/*DiskInfo*/
try {
- d.diskInfo.totalDiskCapacity =
- std::stoull(safeGet("TotalDiskCapacity"));
- d.diskInfo.totalDataCapacity =
- std::stoull(safeGet("TotalDataCapacity"));
- d.diskInfo.totalSystemCapacity =
- std::stoull(safeGet("TotalSystemCapacity"));
+ auto safeParseU64 = [&](const char *key) -> uint64_t {
+ std::string s = safeGet(key);
+ if (s.empty())
+ return 0;
+ try {
+ return std::stoull(s);
+ } catch (...) {
+ qDebug() << "Failed to parse key to uint64_t:" << key
+ << "value:" << QString::fromStdString(s);
+ return 0;
+ }
+ };
+ d.diskInfo.totalDiskCapacity = safeParseU64("TotalDiskCapacity");
+ d.diskInfo.totalDataCapacity = safeParseU64("TotalDataCapacity");
+ d.diskInfo.totalSystemCapacity = safeParseU64("TotalSystemCapacity");
/*
For some reason this is way inaccrutate for iOS 17 and up
*/
- d.diskInfo.totalDataAvailable =
- std::stoull(safeGet("TotalDataAvailable"));
+ d.diskInfo.totalDataAvailable = safeParseU64("TotalDataAvailable");
try {
/*
@@ -226,13 +239,19 @@ DeviceInfo fullDeviceInfo(const pugi::xml_document &doc,
// "FSTotalBytes: 63966400512"
// "FSFreeBytes: 2867101696"
// "FSBlockSize: 4096"
- char **info = NULL;
- afc_get_device_info(afcClient, &info);
- if (info && info[6]) {
- d.diskInfo.totalDataAvailable =
- std::stoull(std::string(info[5]));
+ AfcDeviceInfo *info = new AfcDeviceInfo();
+ IdeviceFfiError *err = afc_get_device_info(afcClient, info);
+ if (err) {
+ qDebug() << "AFC get device info error code: " << err->message;
+ return d;
}
- afc_dictionary_free(info);
+ if (info) {
+
+ qDebug() << "AFC Disk Info" << info->free_bytes;
+ d.diskInfo.totalDataAvailable = info->free_bytes;
+ }
+ // FIXME: free
+ afc_device_info_free(info);
} catch (const std::exception &e) {
qDebug() << "Error parsing disk info: " << e.what();
}
@@ -281,14 +300,14 @@ DeviceInfo fullDeviceInfo(const pugi::xml_document &doc,
/*BatteryInfo*/
plist_t diagnostics = nullptr;
- get_battery_info(rawProductType, result.device, d.is_iPhone, diagnostics);
+ get_battery_info(provider, diagnostics);
if (!diagnostics) {
qDebug() << "Failed to get diagnostics plist.";
return d;
}
try {
- PlistNavigator ioreg = PlistNavigator(diagnostics)["IORegistry"];
+ PlistNavigator ioreg = PlistNavigator(diagnostics);
// old devices do not have "BatteryData"
d.oldDevice = !ioreg["BatteryData"];
@@ -329,6 +348,7 @@ DeviceInfo fullDeviceInfo(const pugi::xml_document &doc,
d.batteryInfo.serialNumber = !batterySerialNumber.empty()
? batterySerialNumber
: "Error retrieving serial number";
+ qDebug() << "Cycle count: " << cycleCount;
parseDeviceBattery(ioreg, d);
plist_free(diagnostics);
diagnostics = nullptr;
@@ -340,156 +360,289 @@ DeviceInfo fullDeviceInfo(const pugi::xml_document &doc,
}
}
-iDescriptorInitDeviceResult init_idescriptor_device(const char *udid)
+// [DeviceMonitor] Device connected: "a5c08c1dfdc9fcf81366bd6159c81bba73deaa27"
+// Device added: "a5c08c1dfdc9fcf81366bd6159c81bba73deaa27"
+// Initializing iDescriptor device with UDID:
+// "a5c08c1dfdc9fcf81366bd6159c81bba73deaa27" Failed to create idevice handle
+// Initialization failed, cleaning up resources. FfiInvalidArg
+// init_idescriptor_device success ?: false
+// Failed to initialize device with UDID:
+// "a5c08c1dfdc9fcf81366bd6159c81bba73deaa27"
+iDescriptorInitDeviceResult
+init_idescriptor_device(const QString &udid, WirelessInitArgs wirelessArgs)
{
- qDebug() << "Initializing iDescriptor device with UDID: "
- << QString::fromUtf8(udid);
+ const bool isWireless =
+ !wirelessArgs.ip.isEmpty() && wirelessArgs.pairing_file;
+ qDebug() << "Initializing iDescriptor device with UDID: " << udid
+ << (isWireless ? "over wireless" : "over USB");
+
iDescriptorInitDeviceResult result = {};
- // 1. Initialize all resource handles to nullptr
- idevice_t device = nullptr;
- lockdownd_client_t client = nullptr;
- lockdownd_service_descriptor_t lockdownService = nullptr;
- afc_client_t afcClient = nullptr;
- afc_client_t afc2Client = nullptr;
+ UsbmuxdConnectionHandle *usbmuxd_conn = nullptr;
+ UsbmuxdAddrHandle *addr_handle = nullptr;
+ IdeviceProviderHandle *provider = nullptr;
+ LockdowndClientHandle *lockdown = nullptr;
+ IdeviceSocketHandle *socket = nullptr;
+ AfcClientHandle *afc_client = nullptr;
+ AfcClientHandle *afc2_client = nullptr;
pugi::xml_document infoXml;
+ uint32_t actual_device_id = 0;
+ IdevicePairingFile *pairing_file = nullptr;
+ IdeviceHandle *deviceHandle = nullptr;
+ // FIXME: remove debug
+ std::stringstream ss;
- idevice_error_t ret =
- idevice_new_with_options(&device, udid, IDEVICE_LOOKUP_USBMUX);
+ // 1. Connect to usbmuxd
+ IdeviceFfiError *err =
+ idevice_usbmuxd_new_default_connection(0, &usbmuxd_conn);
+ if (err) {
+ if (!isWireless) {
+ qDebug() << "Failed to connect to usbmuxd";
+ goto cleanup;
+ }
+ }
- if (ret != IDEVICE_E_SUCCESS) {
- qDebug() << "Failed to connect to device: " << ret;
- // result.error is not set here as idevice_error_t is different
+ // 2. Create default address handle
+ err = idevice_usbmuxd_default_addr_new(&addr_handle);
+ if (err) {
+ qDebug() << "Failed to create address handle";
goto cleanup;
}
- lockdownd_error_t ldret;
- if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(
- device, &client, APP_LABEL))) {
- result.error = ldret;
- qDebug() << "Failed to create lockdown client: " << ldret;
- goto cleanup;
- }
-
- if (LOCKDOWN_E_SUCCESS !=
- (ldret = lockdownd_start_service(client, "com.apple.afc",
- &lockdownService))) {
- result.error = ldret;
- qDebug() << "Failed to start AFC service: " << ldret;
- goto cleanup;
- }
-
- if (afc_client_new(device, lockdownService, &afcClient) != AFC_E_SUCCESS) {
- qDebug() << "Failed to create AFC client.";
-
- goto cleanup;
- }
-
- // AFC2 is optional, so we don't goto cleanup on failure
- afc_error_t afc2_err;
- if ((afc2_err = afc2_client_new(device, &afc2Client)) != AFC_E_SUCCESS) {
- qDebug() << "AFC2 client not available. Error:" << afc2_err;
- afc2Client = nullptr;
+ if (isWireless) {
+ // Create IPv4 sockaddr
+ struct sockaddr_in addr_in;
+ memset(&addr_in, 0, sizeof(addr_in));
+ addr_in.sin_family = AF_INET;
+ addr_in.sin_port = htons(0); // Port doesn't matter for provider
+ inet_pton(AF_INET, wirelessArgs.ip.toUtf8().constData(),
+ &addr_in.sin_addr);
+ // IdevicePairingFile *pairing_file = nullptr;
+ // idevice_pairing_file_read(
+ // wirelessArgs.pairing_file.toUtf8().constData(), &pairing_file);
+ err = idevice_tcp_provider_new(
+ (const idevice_sockaddr *)&addr_in,
+ const_cast(wirelessArgs.pairing_file),
+ APP_LABEL, &provider);
+ if (err) {
+ qDebug() << "Failed to create wireless provider";
+ goto cleanup;
+ }
+ // err = heartbeat_new();
+ // heartbeat_connect
} else {
- qDebug() << "AFC2 client created successfully.";
+
+ UsbmuxdDeviceHandle **devices;
+ int device_count;
+ err =
+ idevice_usbmuxd_get_devices(usbmuxd_conn, &devices, &device_count);
+
+ // Find by UDID and get its device_id
+ for (size_t i = 0; i < device_count; i++) {
+ const char *device_udid =
+ idevice_usbmuxd_device_get_udid(devices[i]);
+ if (strcmp(device_udid, udid.toUtf8().constData()) == 0) {
+ actual_device_id =
+ idevice_usbmuxd_device_get_device_id(devices[i]);
+ break;
+ }
+ }
+
+ // 3. Create provider for the device (actual function name)
+ err = usbmuxd_provider_new(addr_handle, 0, udid.toUtf8().constData(),
+ actual_device_id, APP_LABEL, &provider);
}
- get_device_info_xml(udid, client, device, infoXml);
-
- if (infoXml.empty()) {
- qDebug() << "Failed to retrieve device info XML for UDID: "
- << QString::fromUtf8(udid);
+ if (err) {
+ qDebug() << "Failed to create provider";
goto cleanup;
}
- // If we got this far, the core initialization is successful
+ // 4. Connect to lockdown (actual function name)
+ err = lockdownd_connect(provider, &lockdown);
+ if (err) {
+ qDebug() << "Failed to connect to lockdown";
+ goto cleanup;
+ }
+ // err = idevice_new(socket, "iDescriptor", &deviceHandle);
+ // if (err) {
+ // qDebug() << "Failed to create idevice handle";
+ // goto cleanup;
+ // }
+
+ err = idevice_provider_get_pairing_file(provider, &pairing_file);
+ if (err) {
+ qDebug() << "Failed to get pairing file";
+ goto cleanup;
+ }
+
+ err = lockdownd_start_session(lockdown, pairing_file);
+ if (err) {
+ qDebug() << "Failed to start lockdown session";
+ goto cleanup;
+ }
+
+ uint16_t heartbeat_port;
+ bool heartbeat_ssl;
+ if (isWireless) {
+ // err = lockdownd_start_service(lockdown, "com.apple.heartbeat",
+ // &heartbeat_port, &heartbeat_ssl);
+ // if (err) {
+ // qDebug() << "Failed to start Heartbeat service";
+ // goto cleanup;
+ // }
+
+ // Start heartbeat client to keep connection alive
+ HeartbeatClientHandle *heartbeat = nullptr;
+ err = heartbeat_connect(provider, &heartbeat);
+
+ if (err) {
+ qDebug() << "Failed to connect to Heartbeat client";
+ goto cleanup;
+ }
+
+ // // After getting the heartbeat port from lockdown
+ // IdeviceHandle *deviceHandle = nullptr;
+
+ // // Then create IdeviceHandle from the socket
+ // err = idevice_new(socket, "heartbeat", &deviceHandle);
+ // if (err) {
+ // qDebug() << "Failed to create idevice handle";
+ // goto cleanup;
+ // }
+
+ // // Now use with heartbeat_new
+ // HeartbeatClientHandle *heartbeat = nullptr;
+ // err = heartbeat_new(deviceHandle, &heartbeat);
+ // if (err) {
+ // qDebug() << "Failed to create Heartbeat client";
+ // goto cleanup;
+ // }
+
+ qDebug() << "Heartbeat client created successfully";
+ }
+
+ // 5. Start AFC service
+ uint16_t afc_port;
+ bool afc_ssl;
+ err =
+ lockdownd_start_service(lockdown, "com.apple.afc", &afc_port, &afc_ssl);
+ if (err) {
+ qDebug() << "Failed to start AFC service";
+ goto cleanup;
+ }
+
+ // 6. Create AFC client from provider
+ err = afc_client_connect(provider, &afc_client);
+ if (err) {
+ qDebug() << "Failed to create AFC client";
+ goto cleanup;
+ }
+
+ // 7. AFC2 is optional
+ uint16_t afc2_port;
+ bool afc2_ssl;
+ err = lockdownd_start_service(lockdown, "com.apple.afc2", &afc2_port,
+ &afc2_ssl);
+ if (!err) {
+ err = afc_client_connect(provider, &afc2_client);
+ }
+
+ get_device_info_xml(udid.toUtf8().constData(), lockdown, infoXml);
+ infoXml.print(ss, " "); // " " for indentation
+ qDebug().noquote() << "--- Full Device Info XML ---"
+ << QString::fromStdString(ss.str());
+
+ result.device = provider;
result.success = true;
- result.device = device;
- result.afcClient = afcClient;
- result.afc2Client = afc2Client;
- fullDeviceInfo(infoXml, afcClient, result);
+ result.afcClient = afc_client;
+ result.afc2Client = afc2_client;
+ result.lockdown = lockdown;
+ AppContext::sharedInstance()->cachePairingFile(udid, pairing_file);
+ fullDeviceInfo(infoXml, afc_client, provider, result);
cleanup:
- if (lockdownService) {
- lockdownd_service_descriptor_free(lockdownService);
- }
- if (client) {
- lockdownd_client_free(client);
- }
-
- // free on error
+ // Cleanup on error
+ // FIXME: implement proper cleanup
+ // one of them causes a crash here, needs investigation
if (!result.success) {
- if (afc2Client) {
- afc_client_free(afc2Client);
- }
- if (afcClient) {
- afc_client_free(afcClient);
- }
- if (device) {
- idevice_free(device);
- }
+ qDebug() << "Initialization failed, cleaning up resources."
+ << err->message;
+ // if (afc2_client)
+ // afc_client_free(afc2_client);
+ // if (afc_client)
+ // afc_client_free(afc_client);
+ // if (lockdown)
+ // lockdownd_client_free(lockdown);
+ // if (provider)
+ // idevice_provider_free(provider);
+ // if (addr_handle)
+ // idevice_usbmuxd_addr_free(addr_handle);
+ // if (usbmuxd_conn)
+ // idevice_usbmuxd_connection_free(usbmuxd_conn);
}
return result;
}
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-iDescriptorInitDeviceResultRecovery
-init_idescriptor_recovery_device(uint64_t ecid)
-{
- qDebug() << "Initializing iDescriptor recovery device with ECID: " << ecid;
- iDescriptorInitDeviceResultRecovery result = {};
- irecv_client_t client = nullptr;
- const irecv_device_info *deviceInfo = nullptr;
- irecv_device_t device = nullptr;
- const DeviceDatabaseInfo *info = nullptr;
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// iDescriptorInitDeviceResultRecovery
+// init_idescriptor_recovery_device(uint64_t ecid)
+// {
+// qDebug() << "Initializing iDescriptor recovery device with ECID: " <<
+// ecid; iDescriptorInitDeviceResultRecovery result = {};
- irecv_error_t ret = irecv_open_with_ecid_and_attempts(
- &client, ecid, RECOVERY_CLIENT_CONNECTION_TRIES);
+// irecv_client_t client = nullptr;
+// const irecv_device_info *deviceInfo = nullptr;
+// irecv_device_t device = nullptr;
+// const DeviceDatabaseInfo *info = nullptr;
- if (ret != IRECV_E_SUCCESS) {
- qDebug() << "Failed to open recovery client with ECID:" << ecid
- << "Error:" << ret;
- result.error = ret;
- goto cleanup;
- }
+// irecv_error_t ret = irecv_open_with_ecid_and_attempts(
+// &client, ecid, RECOVERY_CLIENT_CONNECTION_TRIES);
- ret = irecv_get_mode(client, (int *)&result.mode);
- if (ret != IRECV_E_SUCCESS) {
- qDebug() << "Failed to get recovery mode. Error:" << ret;
- result.error = ret;
- goto cleanup;
- }
+// if (ret != IRECV_E_SUCCESS) {
+// qDebug() << "Failed to open recovery client with ECID:" << ecid
+// << "Error:" << ret;
+// result.error = ret;
+// goto cleanup;
+// }
- deviceInfo = irecv_get_device_info(client);
- if (!deviceInfo) {
- qDebug() << "Failed to get device info from recovery client";
- result.error = IRECV_E_UNKNOWN_ERROR;
- goto cleanup;
- }
+// ret = irecv_get_mode(client, (int *)&result.mode);
+// if (ret != IRECV_E_SUCCESS) {
+// qDebug() << "Failed to get recovery mode. Error:" << ret;
+// result.error = ret;
+// goto cleanup;
+// }
- if (irecv_devices_get_device_by_client(client, &device) ==
- IRECV_E_SUCCESS &&
- device && device->hardware_model) {
- qDebug() << "Recovery device hardware_model: "
- << device->hardware_model;
- info =
- DeviceDatabase::findByHwModel(std::string(device->hardware_model));
- } else {
- qDebug() << "Could not resolve hardware_model from client.";
- }
+// deviceInfo = irecv_get_device_info(client);
+// if (!deviceInfo) {
+// qDebug() << "Failed to get device info from recovery client";
+// result.error = IRECV_E_UNKNOWN_ERROR;
+// goto cleanup;
+// }
- result.displayName =
- info ? (info->displayName ? info->displayName : info->marketingName)
- : "Unknown Device";
- result.deviceInfo = *deviceInfo;
- result.success = true;
+// if (irecv_devices_get_device_by_client(client, &device) ==
+// IRECV_E_SUCCESS &&
+// device && device->hardware_model) {
+// qDebug() << "Recovery device hardware_model: "
+// << device->hardware_model;
+// info =
+// DeviceDatabase::findByHwModel(std::string(device->hardware_model));
+// } else {
+// qDebug() << "Could not resolve hardware_model from client.";
+// }
-cleanup:
- if (client) {
- irecv_close(client);
- }
+// result.displayName =
+// info ? (info->displayName ? info->displayName : info->marketingName)
+// : "Unknown Device";
+// result.deviceInfo = *deviceInfo;
+// result.success = true;
- return result;
-}
-#endif // ENABLE_RECOVERY_DEVICE_SUPPORT
\ No newline at end of file
+// cleanup:
+// if (client) {
+// irecv_close(client);
+// }
+
+// return result;
+// }
+// #endif // ENABLE_RECOVERY_DEVICE_SUPPORT
\ No newline at end of file
diff --git a/src/deviceimagewidget.cpp b/src/deviceimagewidget.cpp
index 6723686..8b361ef 100644
--- a/src/deviceimagewidget.cpp
+++ b/src/deviceimagewidget.cpp
@@ -18,13 +18,13 @@
*/
#include "deviceimagewidget.h"
+#include "iDescriptor.h"
#include
#include
#include
#include
#include
#include
-#include
DeviceImageWidget::DeviceImageWidget(iDescriptorDevice *device, QWidget *parent)
: QWidget(parent), m_device(device)
@@ -161,7 +161,7 @@ QString DeviceImageWidget::getMockupNameFromDisplayName(
int DeviceImageWidget::getIosVersionFromDevice() const
{
- unsigned int version = idevice_get_device_version(m_device->device);
+ unsigned int version = m_device->deviceInfo.parsedDeviceVersion;
if (version > 0) {
int majorVersion = (version >> 16) & 0xFF;
@@ -180,7 +180,7 @@ int DeviceImageWidget::getIosVersionFromDevice() const
}
}
- // If all else fails, return unknown version (will use ios26 wallpaper)
+ // return unknown version (will use ios26 wallpaper)
return 0;
}
diff --git a/src/deviceinfowidget.cpp b/src/deviceinfowidget.cpp
index 7f02ea0..047f226 100644
--- a/src/deviceinfowidget.cpp
+++ b/src/deviceinfowidget.cpp
@@ -20,12 +20,12 @@
#include "deviceinfowidget.h"
#include "batterywidget.h"
#include "diskusagewidget.h"
-#include "fileexplorerwidget.h"
+// #include "fileexplorerwidget.h"
#include "iDescriptor-ui.h"
#include "iDescriptor.h"
#include "infolabel.h"
#include "privateinfolabel.h"
-#include "toolboxwidget.h"
+// #include "toolboxwidget.h"
#include
#include
#include
@@ -78,20 +78,20 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
QIcon(":/resources/icons/IcOutlinePowerSettingsNew.png"), "Shutdown",
this);
shutdownBtn->setIconSize(QSize(20, 20));
- connect(shutdownBtn, &ZIconWidget::clicked, this,
- [device]() { ToolboxWidget::shutdownDevice(device); });
+ // connect(shutdownBtn, &ZIconWidget::clicked, this,
+ // [device]() { ToolboxWidget::shutdownDevice(device); });
ZIconWidget *restartBtn = new ZIconWidget(
QIcon(":/resources/icons/IcTwotoneRestartAlt.png"), "Restart", this);
restartBtn->setIconSize(QSize(20, 20));
- connect(restartBtn, &ZIconWidget::clicked, this,
- [device]() { ToolboxWidget::restartDevice(device); });
+ // connect(restartBtn, &ZIconWidget::clicked, this,
+ // [device]() { ToolboxWidget::restartDevice(device); });
ZIconWidget *recoveryBtn = new ZIconWidget(
QIcon(":/resources/icons/HugeiconsWrench01.png"), "Recovery", this);
recoveryBtn->setIconSize(QSize(20, 20));
- connect(recoveryBtn, &ZIconWidget::clicked, this,
- [device]() { ToolboxWidget::_enterRecoveryMode(device); });
+ // connect(recoveryBtn, &ZIconWidget::clicked, this,
+ // [device]() { ToolboxWidget::_enterRecoveryMode(device); });
actionsLayout->addWidget(shutdownBtn);
actionsLayout->addWidget(restartBtn);
@@ -259,25 +259,27 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
infoItems.append(
{"Hardware Platform:", createValueLabel(QString::fromStdString(
device->deviceInfo.hardwarePlatform))});
- infoItems.append(
- {"Battery Cycle:", createValueLabel(QString::number(
- m_device->deviceInfo.batteryInfo.cycleCount))});
+ // infoItems.append(
+ // {"Battery Cycle:", createValueLabel(QString::number(
+ // m_device->deviceInfo.batteryInfo.cycleCount))});
infoItems.append(
{"Firmware Version:", createValueLabel(QString::fromStdString(
device->deviceInfo.firmwareVersion))});
- // Battery Info
- QWidget *batteryWidget = new QWidget();
- QHBoxLayout *batteryLayout = new QHBoxLayout(batteryWidget);
- batteryLayout->setContentsMargins(0, 0, 0, 0);
- batteryLayout->setSpacing(5);
- batteryLayout->addWidget(new QLabel(device->deviceInfo.batteryInfo.health));
- QPushButton *moreButton = new QPushButton("More");
- connect(moreButton, &QPushButton::clicked, this,
- &DeviceInfoWidget::onBatteryMoreClicked);
- batteryLayout->addWidget(moreButton);
- batteryLayout->addStretch();
- infoItems.append({"Battery Health:", batteryWidget});
+ // // FIXME: Battery Info
+ // // QWidget *batteryWidget = new QWidget();
+ // // QHBoxLayout *batteryLayout = new QHBoxLayout(batteryWidget);
+ // // batteryLayout->setContentsMargins(0, 0, 0, 0);
+ // // batteryLayout->setSpacing(5);
+ // // batteryLayout->addWidget(new
+ // // QLabel(device->deviceInfo.batteryInfo.health)); QPushButton
+ // *moreButton =
+ // // new QPushButton("More"); connect(moreButton, &QPushButton::clicked,
+ // this,
+ // // &DeviceInfoWidget::onBatteryMoreClicked);
+ // // batteryLayout->addWidget(moreButton);
+ // // batteryLayout->addStretch();
+ // // infoItems.append({"Battery Health:", batteryWidget});
infoItems.append(
{"Production Device:",
@@ -322,7 +324,7 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
}
infoLayout->addWidget(gridContainer);
- // infoLayout->addStretch(); // Pushes footer to the bottom
+ infoLayout->addStretch(); // Pushes footer to the bottom
// Footer
QLabel *footerLabel =
@@ -341,16 +343,16 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
rightSideLayout->addWidget(new DiskUsageWidget(device, this));
rightSideLayout->addStretch();
- // TODO: layout shift cause ?
- // rightSideLayout->setAlignment(Qt::AlignCenter);
+ // // TODO: layout shift cause ?
+ // // rightSideLayout->setAlignment(Qt::AlignCenter);
mainLayout->addLayout(rightSideLayout);
mainLayout->addStretch();
- m_updateTimer = new QTimer(this);
- connect(m_updateTimer, &QTimer::timeout, this,
- &DeviceInfoWidget::updateBatteryInfo);
- m_updateTimer->start(30000); // Update every 30 seconds
+ // m_updateTimer = new QTimer(this);
+ // connect(m_updateTimer, &QTimer::timeout, this,
+ // &DeviceInfoWidget::updateBatteryInfo);
+ // m_updateTimer->start(30000); // Update every 30 seconds
}
DeviceInfoWidget::~DeviceInfoWidget() {}
@@ -370,47 +372,47 @@ void DeviceInfoWidget::onBatteryMoreClicked()
void DeviceInfoWidget::updateBatteryInfo()
{
- qDebug() << "Updating battery info...";
- plist_t diagnostics = nullptr;
- get_battery_info(m_device->deviceInfo.rawProductType, m_device->device,
- m_device->deviceInfo.is_iPhone, diagnostics);
+ // qDebug() << "Updating battery info...";
+ // plist_t diagnostics = nullptr;
+ // get_battery_info(m_device->deviceInfo.rawProductType, m_device->device,
+ // m_device->deviceInfo.is_iPhone, diagnostics);
- if (!diagnostics) {
- qDebug() << "Failed to get diagnostics plist.";
- return;
- }
- /*DATA*/
- DeviceInfo &d = m_device->deviceInfo;
- qDebug() << "old device" << d.oldDevice;
- PlistNavigator ioreg = PlistNavigator(diagnostics)["IORegistry"];
- if (d.oldDevice)
- parseOldDeviceBattery(ioreg, d);
- else
- parseDeviceBattery(ioreg, d);
- /*UI*/
- updateChargingStatusIcon();
- m_chargingWattsWithCableTypeLabel->setText(
- QString::number(d.batteryInfo.watts) + "W" + "/" +
- (d.batteryInfo.usbConnectionType == BatteryInfo::ConnectionType::USB
- ? "USB"
- : "USB-C"));
+ // if (!diagnostics) {
+ // qDebug() << "Failed to get diagnostics plist.";
+ // return;
+ // }
+ // /*DATA*/
+ // DeviceInfo &d = m_device->deviceInfo;
+ // qDebug() << "old device" << d.oldDevice;
+ // PlistNavigator ioreg = PlistNavigator(diagnostics)["IORegistry"];
+ // // if (d.oldDevice)
+ // // parseOldDeviceBattery(ioreg, d);
+ // // else
+ // // parseDeviceBattery(ioreg, d);
+ // /*UI*/
+ // updateChargingStatusIcon();
+ // m_chargingWattsWithCableTypeLabel->setText(
+ // QString::number(d.batteryInfo.watts) + "W" + "/" +
+ // (d.batteryInfo.usbConnectionType == BatteryInfo::ConnectionType::USB
+ // ? "USB"
+ // : "USB-C"));
- m_batteryWidget->updateContext(
- d.batteryInfo.isCharging,
- qBound(1, d.batteryInfo.currentBatteryLevel, 100));
+ // m_batteryWidget->updateContext(
+ // d.batteryInfo.isCharging,
+ // qBound(1, d.batteryInfo.currentBatteryLevel, 100));
}
void DeviceInfoWidget::updateChargingStatusIcon()
{
- if (m_device->deviceInfo.batteryInfo.isCharging) {
- m_chargingStatusLabel->setText("Charging");
- m_chargingStatusLabel->setStyleSheet(
- QString("color: %1;").arg(COLOR_GREEN.name()));
- m_lightningIconLabel->show();
+ // if (m_device->deviceInfo.batteryInfo.isCharging) {
+ // m_chargingStatusLabel->setText("Charging");
+ // m_chargingStatusLabel->setStyleSheet(
+ // QString("color: %1;").arg(COLOR_GREEN.name()));
+ // m_lightningIconLabel->show();
- } else {
- m_chargingStatusLabel->setText("Not Charging");
- m_chargingStatusLabel->setStyleSheet("");
- m_lightningIconLabel->hide();
- }
+ // } else {
+ // m_chargingStatusLabel->setText("Not Charging");
+ // m_chargingStatusLabel->setStyleSheet("");
+ // m_lightningIconLabel->hide();
+ // }
}
\ No newline at end of file
diff --git a/src/devicemanagerwidget.cpp b/src/devicemanagerwidget.cpp
index 508f209..9a9accd 100644
--- a/src/devicemanagerwidget.cpp
+++ b/src/devicemanagerwidget.cpp
@@ -20,10 +20,10 @@
#include "devicemanagerwidget.h"
#include "appcontext.h"
#include "devicemenuwidget.h"
-#include "devicependingwidget.h"
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-#include "recoverydeviceinfowidget.h"
-#endif
+// #include "devicependingwidget.h"
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// #include "recoverydeviceinfowidget.h"
+// #endif
#include "settingsmanager.h"
#include
@@ -37,12 +37,12 @@ DeviceManagerWidget::DeviceManagerWidget(QWidget *parent)
addDevice(device);
// Apply settings-based behavior for switching to new device
- SettingsManager::sharedInstance()->doIfEnabled(
- SettingsManager::Setting::SwitchToNewDevice,
- [this, device]() {
- AppContext::sharedInstance()->setCurrentDeviceSelection(
- DeviceSelection(device->udid));
- });
+ // SettingsManager::sharedInstance()->doIfEnabled(
+ // SettingsManager::Setting::SwitchToNewDevice,
+ // [this, device]() {
+ // AppContext::sharedInstance()->setCurrentDeviceSelection(
+ // DeviceSelection(device->udid));
+ // });
emit updateNoDevicesConnected();
});
@@ -72,29 +72,32 @@ DeviceManagerWidget::DeviceManagerWidget(QWidget *parent)
connect(AppContext::sharedInstance(), &AppContext::devicePaired, this,
[this](iDescriptorDevice *device) {
addPairedDevice(device);
- SettingsManager::sharedInstance()->doIfEnabled(
- SettingsManager::Setting::SwitchToNewDevice,
- [this, device]() {
- AppContext::sharedInstance()->setCurrentDeviceSelection(
- DeviceSelection(device->udid));
- });
+ // SettingsManager::sharedInstance()->doIfEnabled(
+ // SettingsManager::Setting::SwitchToNewDevice,
+ // [this, device]() {
+ // AppContext::sharedInstance()->setCurrentDeviceSelection(
+ // DeviceSelection(device->udid));
+ // });
emit updateNoDevicesConnected();
});
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- connect(AppContext::sharedInstance(), &AppContext::recoveryDeviceAdded,
- this, [this](const iDescriptorRecoveryDevice *recoveryDeviceInfo) {
- addRecoveryDevice(recoveryDeviceInfo);
- emit updateNoDevicesConnected();
- });
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // connect(AppContext::sharedInstance(),
+ // &AppContext::recoveryDeviceAdded,
+ // this, [this](const iDescriptorRecoveryDevice
+ // *recoveryDeviceInfo) {
+ // addRecoveryDevice(recoveryDeviceInfo);
+ // emit updateNoDevicesConnected();
+ // });
- connect(AppContext::sharedInstance(), &AppContext::recoveryDeviceRemoved,
- this, [this](uint64_t ecid) {
- removeRecoveryDevice(ecid);
- emit updateNoDevicesConnected();
- });
-#endif
+ // connect(AppContext::sharedInstance(),
+ // &AppContext::recoveryDeviceRemoved,
+ // this, [this](uint64_t ecid) {
+ // removeRecoveryDevice(ecid);
+ // emit updateNoDevicesConnected();
+ // });
+ // #endif
connect(AppContext::sharedInstance(), &AppContext::devicePairingExpired,
this, [this](const QString &udid) {
@@ -146,94 +149,97 @@ void DeviceManagerWidget::addDevice(iDescriptorDevice *device)
std::pair{deviceWidget, m_sidebar->addDevice(tabTitle, device->udid)};
}
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-void DeviceManagerWidget::addRecoveryDevice(
- const iDescriptorRecoveryDevice *device)
-{
- try {
- // Create device info widget
- RecoveryDeviceInfoWidget *recoveryDeviceInfoWidget =
- new RecoveryDeviceInfoWidget(device);
- m_recoveryDeviceWidgets.insert(
- device->ecid,
- std::pair{recoveryDeviceInfoWidget,
- m_sidebar->addRecoveryDevice(device->ecid)});
- m_stackedWidget->addWidget(recoveryDeviceInfoWidget);
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// void DeviceManagerWidget::addRecoveryDevice(
+// const iDescriptorRecoveryDevice *device)
+// {
+// try {
+// // Create device info widget
+// RecoveryDeviceInfoWidget *recoveryDeviceInfoWidget =
+// new RecoveryDeviceInfoWidget(device);
+// m_recoveryDeviceWidgets.insert(
+// device->ecid,
+// std::pair{recoveryDeviceInfoWidget,
+// m_sidebar->addRecoveryDevice(device->ecid)});
+// m_stackedWidget->addWidget(recoveryDeviceInfoWidget);
- } catch (...) {
- qDebug() << "Error initializing recovery device";
- }
-}
+// } catch (...) {
+// qDebug() << "Error initializing recovery device";
+// }
+// }
-void DeviceManagerWidget::removeRecoveryDevice(uint64_t ecid)
-{
- qDebug() << "Removing recovery device with ECID:" << ecid;
- if (!m_recoveryDeviceWidgets.contains(ecid)) {
- qDebug() << "Recovery device with ECID" + QString::number(ecid) +
- " not found. Please report this issue.";
- return;
- }
+// void DeviceManagerWidget::removeRecoveryDevice(uint64_t ecid)
+// {
+// qDebug() << "Removing recovery device with ECID:" << ecid;
+// if (!m_recoveryDeviceWidgets.contains(ecid)) {
+// qDebug() << "Recovery device with ECID" + QString::number(ecid) +
+// " not found. Please report this issue.";
+// return;
+// }
- RecoveryDeviceInfoWidget *deviceWidget =
- m_recoveryDeviceWidgets[ecid].first;
- RecoveryDeviceSidebarItem *sidebarItem =
- m_recoveryDeviceWidgets[ecid].second;
+// RecoveryDeviceInfoWidget *deviceWidget =
+// m_recoveryDeviceWidgets[ecid].first;
+// RecoveryDeviceSidebarItem *sidebarItem =
+// m_recoveryDeviceWidgets[ecid].second;
- if (deviceWidget != nullptr && sidebarItem != nullptr) {
- qDebug() << "Recovery device exists removing:" << QString::number(ecid);
+// if (deviceWidget != nullptr && sidebarItem != nullptr) {
+// qDebug() << "Recovery device exists removing:" <<
+// QString::number(ecid);
- m_recoveryDeviceWidgets.remove(ecid);
- m_stackedWidget->removeWidget(deviceWidget);
- m_sidebar->removeRecoveryDevice(ecid);
- deviceWidget->deleteLater();
+// m_recoveryDeviceWidgets.remove(ecid);
+// m_stackedWidget->removeWidget(deviceWidget);
+// m_sidebar->removeRecoveryDevice(ecid);
+// deviceWidget->deleteLater();
- emit updateNoDevicesConnected();
- }
-}
-#endif
+// emit updateNoDevicesConnected();
+// }
+// }
+// #endif
void DeviceManagerWidget::addPendingDevice(const QString &udid, bool locked)
{
- qDebug() << "Adding pending device:" << udid;
- if (m_pendingDeviceWidgets.contains(udid.toStdString()) && !locked) {
- qDebug() << "Pending device already exists, moving to next state:"
- << udid;
- m_pendingDeviceWidgets[udid.toStdString()].first->next();
- return;
- } else if (m_pendingDeviceWidgets.contains(udid.toStdString()) && locked) {
- // Already exists and still locked, do nothing
- qDebug()
- << "Pending device already exists and is locked, doing nothing:"
- << udid;
- return;
- }
+ // qDebug() << "Adding pending device:" << udid;
+ // if (m_pendingDeviceWidgets.contains(udid.toStdString()) && !locked) {
+ // qDebug() << "Pending device already exists, moving to next state:"
+ // << udid;
+ // m_pendingDeviceWidgets[udid.toStdString()].first->next();
+ // return;
+ // } else if (m_pendingDeviceWidgets.contains(udid.toStdString()) && locked)
+ // {
+ // // Already exists and still locked, do nothing
+ // qDebug()
+ // << "Pending device already exists and is locked, doing nothing:"
+ // << udid;
+ // return;
+ // }
- qDebug() << "Created pending widget for:" << udid << "Locked:" << locked;
- DevicePendingWidget *pendingWidget = new DevicePendingWidget(locked, this);
- m_stackedWidget->addWidget(pendingWidget);
- m_pendingDeviceWidgets[udid.toStdString()] =
- std::pair{pendingWidget, m_sidebar->addPendingDevice(udid)};
+ // qDebug() << "Created pending widget for:" << udid << "Locked:" << locked;
+ // DevicePendingWidget *pendingWidget = new DevicePendingWidget(locked,
+ // this); m_stackedWidget->addWidget(pendingWidget);
+ // m_pendingDeviceWidgets[udid.toStdString()] =
+ // std::pair{pendingWidget, m_sidebar->addPendingDevice(udid)};
}
void DeviceManagerWidget::removePendingDevice(const QString &udid)
{
- qDebug() << "Removing pending device:" << udid;
- if (!m_pendingDeviceWidgets.contains(udid.toStdString())) {
- qDebug() << "Pending device not found:" << udid;
- return;
- }
- std::string udidStr = udid.toStdString();
- DevicePendingWidget *deviceWidget = m_pendingDeviceWidgets[udidStr].first;
- DevicePendingSidebarItem *sidebarItem =
- m_pendingDeviceWidgets[udidStr].second;
+ // qDebug() << "Removing pending device:" << udid;
+ // if (!m_pendingDeviceWidgets.contains(udid.toStdString())) {
+ // qDebug() << "Pending device not found:" << udid;
+ // return;
+ // }
+ // std::string udidStr = udid.toStdString();
+ // DevicePendingWidget *deviceWidget =
+ // m_pendingDeviceWidgets[udidStr].first; DevicePendingSidebarItem
+ // *sidebarItem =
+ // m_pendingDeviceWidgets[udidStr].second;
- if (deviceWidget != nullptr && sidebarItem != nullptr) {
- qDebug() << "Pending device exists removing:" << udid;
- m_pendingDeviceWidgets.remove(udidStr);
- m_stackedWidget->removeWidget(deviceWidget);
- m_sidebar->removePendingDevice(udidStr);
- deviceWidget->deleteLater();
- }
+ // if (deviceWidget != nullptr && sidebarItem != nullptr) {
+ // qDebug() << "Pending device exists removing:" << udid;
+ // m_pendingDeviceWidgets.remove(udidStr);
+ // m_stackedWidget->removeWidget(deviceWidget);
+ // m_sidebar->removePendingDevice(udidStr);
+ // deviceWidget->deleteLater();
+ // }
}
void DeviceManagerWidget::addPairedDevice(iDescriptorDevice *device)
@@ -335,18 +341,19 @@ void DeviceManagerWidget::onDeviceSelectionChanged(
}
break;
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- case DeviceSelection::Recovery:
- if (m_recoveryDeviceWidgets.contains(selection.ecid)) {
- QWidget *tabWidget = m_recoveryDeviceWidgets[selection.ecid].first;
- if (tabWidget) {
- m_stackedWidget->setCurrentWidget(tabWidget);
- // Clear current device since we're viewing recovery device
- m_currentDeviceUuid = "";
- }
- }
- break;
-#endif
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // case DeviceSelection::Recovery:
+ // if (m_recoveryDeviceWidgets.contains(selection.ecid)) {
+ // QWidget *tabWidget =
+ // m_recoveryDeviceWidgets[selection.ecid].first; if
+ // (tabWidget) {
+ // m_stackedWidget->setCurrentWidget(tabWidget);
+ // // Clear current device since we're viewing recovery
+ // device m_currentDeviceUuid = "";
+ // }
+ // }
+ // break;
+ // #endif
case DeviceSelection::Pending:
if (m_pendingDeviceWidgets.contains(selection.udid)) {
diff --git a/src/devicemanagerwidget.h b/src/devicemanagerwidget.h
index 8f9f574..deb8a83 100644
--- a/src/devicemanagerwidget.h
+++ b/src/devicemanagerwidget.h
@@ -24,9 +24,9 @@
#include "devicependingwidget.h"
#include "devicesidebarwidget.h"
#include "iDescriptor.h"
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-#include "recoverydeviceinfowidget.h"
-#endif
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// #include "recoverydeviceinfowidget.h"
+// #endif
#include
#include
#include
@@ -53,10 +53,10 @@ private:
void addDevice(iDescriptorDevice *device);
void removeDevice(const std::string &uuid);
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- void addRecoveryDevice(const iDescriptorRecoveryDevice *device);
- void removeRecoveryDevice(uint64_t ecid);
-#endif
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // void addRecoveryDevice(const iDescriptorRecoveryDevice *device);
+ // void removeRecoveryDevice(uint64_t ecid);
+ // #endif
void addPendingDevice(const QString &udid, bool locked);
void addPairedDevice(iDescriptorDevice *device);
void removePendingDevice(const QString &udid);
@@ -72,11 +72,12 @@ private:
std::pair>
m_pendingDeviceWidgets; // Map to store devices by UDID
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- QMap>
- m_recoveryDeviceWidgets; // Map to store recovery devices by ECID
-#endif
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // QMap>
+ // m_recoveryDeviceWidgets; // Map to store recovery devices by ECID
+ // #endif
std::string m_currentDeviceUuid;
};
diff --git a/src/devicemenuwidget.cpp b/src/devicemenuwidget.cpp
index aa051b9..def6524 100644
--- a/src/devicemenuwidget.cpp
+++ b/src/devicemenuwidget.cpp
@@ -55,30 +55,30 @@ void DeviceMenuWidget::init()
// Create and add widgets to the stacked widget
m_deviceInfoWidget = new DeviceInfoWidget(device, this);
- m_installedAppsWidget = new InstalledAppsWidget(device, this);
- m_galleryWidget = new GalleryWidget(device, this);
- m_fileExplorerWidget = new FileExplorerWidget(device, this);
+ // m_installedAppsWidget = new InstalledAppsWidget(device, this);
+ // m_galleryWidget = new GalleryWidget(device, this);
+ // m_fileExplorerWidget = new FileExplorerWidget(device, this);
// Set minimum heights
- m_galleryWidget->setMinimumHeight(300);
- m_fileExplorerWidget->setMinimumHeight(300);
+ // m_galleryWidget->setMinimumHeight(300);
+ // m_fileExplorerWidget->setMinimumHeight(300);
- stackedWidget->addWidget(m_deviceInfoWidget); // Index 0 - Info
- stackedWidget->addWidget(m_installedAppsWidget); // Index 1 - Apps
- stackedWidget->addWidget(m_galleryWidget); // Index 2 - Gallery
- stackedWidget->addWidget(m_fileExplorerWidget); // Index 3 - Files
+ stackedWidget->addWidget(m_deviceInfoWidget); // Index 0 - Info
+ // stackedWidget->addWidget(m_installedAppsWidget); // Index 1 - Apps
+ // stackedWidget->addWidget(m_galleryWidget); // Index 2 - Gallery
+ // stackedWidget->addWidget(m_fileExplorerWidget); // Index 3 - Files
// Set default to Info tab
stackedWidget->setCurrentWidget(m_deviceInfoWidget);
// Connect to current changed signal for lazy loading
- connect(stackedWidget, &QStackedWidget::currentChanged, this,
- [this](int index) {
- if (index == 2) { // Gallery tab
- qDebug() << "Switched to Gallery tab";
- m_galleryWidget->load();
- }
- });
+ // connect(stackedWidget, &QStackedWidget::currentChanged, this,
+ // [this](int index) {
+ // if (index == 2) { // Gallery tab
+ // qDebug() << "Switched to Gallery tab";
+ // m_galleryWidget->load();
+ // }
+ // });
QWidget *loadingWidget = stackedWidget->widget(0);
stackedWidget->removeWidget(loadingWidget);
@@ -89,12 +89,12 @@ void DeviceMenuWidget::switchToTab(const QString &tabName)
{
if (tabName == "Info") {
stackedWidget->setCurrentWidget(m_deviceInfoWidget);
- } else if (tabName == "Apps") {
- stackedWidget->setCurrentWidget(m_installedAppsWidget);
- } else if (tabName == "Gallery") {
- stackedWidget->setCurrentWidget(m_galleryWidget);
+ // } else if (tabName == "Apps") {
+ // stackedWidget->setCurrentWidget(m_installedAppsWidget);
+ // } else if (tabName == "Gallery") {
+ // stackedWidget->setCurrentWidget(m_galleryWidget);
} else if (tabName == "Files") {
- stackedWidget->setCurrentWidget(m_fileExplorerWidget);
+ // stackedWidget->setCurrentWidget(m_fileExplorerWidget);
} else {
qDebug() << "Tab not found:" << tabName;
}
diff --git a/src/devicemenuwidget.h b/src/devicemenuwidget.h
index cf0480a..ea94647 100644
--- a/src/devicemenuwidget.h
+++ b/src/devicemenuwidget.h
@@ -20,10 +20,10 @@
#ifndef DEVICEMENUWIDGET_H
#define DEVICEMENUWIDGET_H
#include "deviceinfowidget.h"
-#include "fileexplorerwidget.h"
+// #include "fileexplorerwidget.h"
#include "gallerywidget.h"
#include "iDescriptor.h"
-#include "installedappswidget.h"
+// #include "installedappswidget.h"
#include
#include
@@ -41,9 +41,9 @@ private:
QStackedWidget *stackedWidget; // Pointer to the stacked widget
iDescriptorDevice *device; // Pointer to the iDescriptor device
DeviceInfoWidget *m_deviceInfoWidget;
- InstalledAppsWidget *m_installedAppsWidget;
- GalleryWidget *m_galleryWidget;
- FileExplorerWidget *m_fileExplorerWidget;
+ // InstalledAppsWidget *m_installedAppsWidget;
+ // GalleryWidget *m_galleryWidget;
+ // FileExplorerWidget *m_fileExplorerWidget;
signals:
};
diff --git a/src/devicemonitor.h b/src/devicemonitor.h
new file mode 100644
index 0000000..c2898aa
--- /dev/null
+++ b/src/devicemonitor.h
@@ -0,0 +1,126 @@
+#ifndef DEVICEMONITOR_H
+#define DEVICEMONITOR_H
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace IdeviceFFI;
+
+class DeviceMonitorThread : public QThread
+{
+ Q_OBJECT
+public:
+ DeviceMonitorThread(QObject *parent = nullptr) : QThread(parent) {}
+
+ void run() override
+ {
+ while (!isInterruptionRequested()) {
+ // Create connection
+ UsbmuxdConnectionHandle *usbmuxd_conn;
+ IdeviceFfiError *err =
+ idevice_usbmuxd_new_default_connection(0, &usbmuxd_conn);
+ if (err) {
+ idevice_error_free(err);
+ QThread::msleep(1000); // Wait before retry
+ continue;
+ }
+
+ UsbmuxdListenerHandle *listener;
+ err = idevice_usbmuxd_listen(usbmuxd_conn, &listener);
+ if (err) {
+ idevice_usbmuxd_connection_free(usbmuxd_conn);
+ idevice_error_free(err);
+ QThread::msleep(1000);
+ continue;
+ }
+
+ // Monitor loop
+ while (!isInterruptionRequested()) {
+ bool connect = false;
+ UsbmuxdDeviceHandle *device;
+ uint32_t disconnect_id;
+
+ err = idevice_usbmuxd_listener_next(listener, &connect, &device,
+ &disconnect_id);
+ qDebug() << "Listening for device connections..." << err
+ << connect;
+ if (err) {
+ // Check if it's just the stream ending (no devices)
+ if (err->code == -1) { // Socket error code
+ qDebug() << "Listener stream ended, reconnecting...";
+ idevice_error_free(err);
+ break; // Break inner loop to reconnect
+ } else {
+ qDebug() << "Real error:" << err->message;
+ idevice_error_free(err);
+ break;
+ }
+ }
+
+ if (connect) {
+ const char *udid = idevice_usbmuxd_device_get_udid(device);
+ uint32_t device_id =
+ idevice_usbmuxd_device_get_device_id(device);
+ uint8_t conn_type =
+ idevice_usbmuxd_device_get_connection_type(device);
+
+ // Skip network devices (same as original callback)
+ if (conn_type == CONNECTION_NETWORK) {
+ qDebug() << "Skipping network device:" << QString(udid);
+ idevice_usbmuxd_device_free(device);
+ continue;
+ }
+
+ deviceMap[device_id] = QString(udid);
+ qDebug()
+ << "[DeviceMonitor] Device connected:" << QString(udid);
+
+ emit deviceEvent(IDEVICE_DEVICE_ADD, QString(udid),
+ conn_type, AddType::Regular);
+ idevice_usbmuxd_device_free(device);
+ } else {
+ QString udid = deviceMap.value(disconnect_id, QString());
+ if (!udid.isEmpty()) {
+ emit deviceEvent(IDEVICE_DEVICE_REMOVE, udid,
+ CONNECTION_USB, AddType::Regular);
+ deviceMap.remove(disconnect_id);
+ } else {
+ qDebug() << "Unknown device disconnected please report "
+ "this issue: "
+ << disconnect_id;
+ }
+ }
+ }
+
+ // Cleanup before reconnecting
+ idevice_usbmuxd_listener_handle_free(listener);
+ idevice_usbmuxd_connection_free(usbmuxd_conn);
+ }
+ }
+
+ enum IdeviceEventType {
+ IDEVICE_DEVICE_ADD = 1,
+ IDEVICE_DEVICE_REMOVE = 2,
+ IDEVICE_DEVICE_PAIRED = 3
+ };
+
+ enum IdeviceConnectionType { CONNECTION_USB = 1, CONNECTION_NETWORK = 2 };
+
+ enum AddType { Regular = 0, Pairing = 1 };
+
+signals:
+ void deviceEvent(int event, const QString &udid, int conn_type,
+ int addType);
+
+private:
+ QMap deviceMap;
+};
+#endif // DEVICEMONITOR_H
\ No newline at end of file
diff --git a/src/diskusagewidget.cpp b/src/diskusagewidget.cpp
index 64eea78..0561698 100644
--- a/src/diskusagewidget.cpp
+++ b/src/diskusagewidget.cpp
@@ -27,9 +27,9 @@
#include
#include
-#include
-#include
-#include
+// #include
+// #include
+// #include
DiskUsageWidget::DiskUsageWidget(iDescriptorDevice *device, QWidget *parent)
: QWidget(parent), m_device(device), m_state(Loading), m_totalCapacity(0),
@@ -95,31 +95,33 @@ void DiskUsageWidget::setupUI()
m_diskBarLayout->setContentsMargins(0, 0, 0, 0);
m_diskBarLayout->setSpacing(0);
-/*
- FIXME: There is bug with qt, related to NSPopover on macOS
- need to revisit this when we find a fix
-*/
-// #ifdef Q_OS_MAC
-// m_systemBar = new DiskUsageBar();
-// m_appsBar = new DiskUsageBar();
-// m_mediaBar = new DiskUsageBar();
-// m_othersBar = new DiskUsageBar();
-// m_freeBar = new DiskUsageBar();
+ /*
+ FIXME: There is bug with qt, related to NSPopover on macOS
+ need to revisit this when we find a fix
+ */
+ // #ifdef Q_OS_MAC
+ // m_systemBar = new DiskUsageBar();
+ // m_appsBar = new DiskUsageBar();
+ // m_mediaBar = new DiskUsageBar();
+ // m_othersBar = new DiskUsageBar();
+ // m_freeBar = new DiskUsageBar();
-// m_systemBar->setStyleSheet(
-// " background-color: #a1384d; border: 1px solid"
-// "#e64a5b; padding: 0; margin: 0; border-top-left-radius: 3px; "
-// "border-bottom-left-radius: 3px; ");
-// m_appsBar->setStyleSheet("background-color: #4f869f; border: 1px solid "
-// "#63b4da; padding: 0; margin: 0; ");
-// m_mediaBar->setStyleSheet("background-color: #2ECC71; "
-// "border: none; padding: 0; margin: 0; ");
-// m_othersBar->setStyleSheet("background-color: #a28729; border: 1px solid "
-// "#c4a32d; padding: 0; margin: 0; ");
-// m_freeBar->setStyleSheet(
-// "background-color: #6e6d6d; border: 1px solid "
-// "#4f4f4f; padding: 0; margin: 0; border-top-right-radius: 3px; "
-// "border-bottom-right-radius: 3px; ");
+ // m_systemBar->setStyleSheet(
+ // " background-color: #a1384d; border: 1px solid"
+ // "#e64a5b; padding: 0; margin: 0; border-top-left-radius: 3px; "
+ // "border-bottom-left-radius: 3px; ");
+ // m_appsBar->setStyleSheet("background-color: #4f869f; border: 1px
+ // solid "
+ // "#63b4da; padding: 0; margin: 0; ");
+ // m_mediaBar->setStyleSheet("background-color: #2ECC71; "
+ // "border: none; padding: 0; margin: 0; ");
+ // m_othersBar->setStyleSheet("background-color: #a28729; border: 1px
+ // solid "
+ // "#c4a32d; padding: 0; margin: 0; ");
+ // m_freeBar->setStyleSheet(
+ // "background-color: #6e6d6d; border: 1px solid "
+ // "#4f4f4f; padding: 0; margin: 0; border-top-right-radius: 3px; "
+ // "border-bottom-right-radius: 3px; ");
m_systemBar = new QWidget();
m_appsBar = new QWidget();
@@ -221,6 +223,7 @@ void DiskUsageWidget::updateUI()
if (m_totalCapacity == 0) {
m_processIndicator->stop();
+ m_processIndicator->hide();
m_statusLabel->setText("No disk information available.");
m_stackedWidget->setCurrentWidget(m_loadingErrorPage);
return;
@@ -318,19 +321,22 @@ void DiskUsageWidget::updateUI()
m_diskBarLayout->setStretchFactor(m_othersBar, othersStretch);
m_diskBarLayout->setStretchFactor(m_freeBar, freeStretch);
-/* FIXME: NSPopover bug */
+ /* FIXME: NSPopover bug */
// #ifdef Q_OS_MAC
-// m_systemBar->setUsageInfo("System", formatSize(m_systemUsage), "#a1384d",
-// (double)m_systemUsage / m_totalCapacity);
-// m_appsBar->setUsageInfo("Apps", formatSize(m_appsUsage), "#3498DB",
-// (double)m_appsUsage / m_totalCapacity);
-// m_mediaBar->setUsageInfo("Media", formatSize(m_mediaUsage), "#2ECC71",
-// (double)m_mediaUsage / m_totalCapacity);
-// m_othersBar->setUsageInfo("Others", formatSize(m_othersUsage), "#F39C12",
-// (double)m_othersUsage / m_totalCapacity);
-// m_freeBar->setUsageInfo("Free", formatSize(m_freeSpace), "#BDC3C7",
-// (double)m_freeSpace / m_totalCapacity);
-// #else
+ // m_systemBar->setUsageInfo("System", formatSize(m_systemUsage),
+ // "#a1384d",
+ // (double)m_systemUsage / m_totalCapacity);
+ // m_appsBar->setUsageInfo("Apps", formatSize(m_appsUsage), "#3498DB",
+ // (double)m_appsUsage / m_totalCapacity);
+ // m_mediaBar->setUsageInfo("Media", formatSize(m_mediaUsage),
+ // "#2ECC71",
+ // (double)m_mediaUsage / m_totalCapacity);
+ // m_othersBar->setUsageInfo("Others", formatSize(m_othersUsage),
+ // "#F39C12",
+ // (double)m_othersUsage / m_totalCapacity);
+ // m_freeBar->setUsageInfo("Free", formatSize(m_freeSpace), "#BDC3C7",
+ // (double)m_freeSpace / m_totalCapacity);
+ // #else
m_systemBar->setToolTip(
QString("System: %1 (%2%)")
.arg(formatSize(m_systemUsage))
@@ -357,7 +363,6 @@ void DiskUsageWidget::updateUI()
.arg(QString::number((double)m_freeSpace / m_totalCapacity * 100,
'f', 1)));
-
// Hide segments with zero usage
// m_systemBar->setVisible(m_systemUsage > 0);
// m_appsBar->setVisible(m_appsUsage > 0);
@@ -365,7 +370,6 @@ void DiskUsageWidget::updateUI()
// m_othersBar->setVisible(m_othersUsage > 0);
// m_freeBar->setVisible(m_freeSpace > 0);
}
-
void DiskUsageWidget::fetchData()
{
auto *watcher = new QFutureWatcher(this);
@@ -376,6 +380,7 @@ void DiskUsageWidget::fetchData()
m_state = Error;
m_errorMessage = result["error"].toString();
} else {
+ qDebug() << "Disk usage data fetched:" << result;
m_totalCapacity = result["totalCapacity"].toULongLong();
m_systemUsage = result["systemUsage"].toULongLong();
m_appsUsage = result["appsUsage"].toULongLong();
@@ -393,17 +398,18 @@ void DiskUsageWidget::fetchData()
m_state = Ready;
}
- updateUI(); // Update the UI instead of triggering repaint
+ updateUI();
watcher->deleteLater();
});
- QFuture future = QtConcurrent::run([this]() {
+ QFuture future = QtConcurrent::run([this]() -> QVariantMap {
QVariantMap result;
if (!m_device || !m_device->device) {
result["error"] = "Invalid device.";
return result;
}
+ // Pre-populate with known info
result["totalCapacity"] = QVariant::fromValue(
m_device->deviceInfo.diskInfo.totalDiskCapacity);
result["freeSpace"] = QVariant::fromValue(
@@ -411,41 +417,21 @@ void DiskUsageWidget::fetchData()
result["systemUsage"] = QVariant::fromValue(
m_device->deviceInfo.diskInfo.totalSystemCapacity);
+ // Create provider wrapper from existing handle
+ Provider provider = Provider::adopt(m_device->device);
+
// Apps usage
uint64_t totalAppsSpace = 0;
- instproxy_client_t instproxy = nullptr;
- lockdownd_client_t lockdownClient = nullptr;
- lockdownd_service_descriptor_t lockdowndService = nullptr;
-
- if (lockdownd_client_new_with_handshake(m_device->device,
- &lockdownClient, APP_LABEL) !=
- LOCKDOWN_E_SUCCESS) {
- result["error"] = "Could not connect to lockdown service.";
+ auto instproxy_res = IdeviceFFI::InstallationProxy::connect(provider);
+ if (instproxy_res.is_err()) {
+ result["error"] =
+ "Could not connect to installation proxy: " +
+ QString::fromStdString(instproxy_res.unwrap_err().message);
return result;
}
+ auto instproxy = std::move(instproxy_res.unwrap());
- if (lockdownd_start_service(lockdownClient,
- "com.apple.mobile.installation_proxy",
- &lockdowndService) != LOCKDOWN_E_SUCCESS) {
- result["error"] = "Could not start installation proxy service.";
- lockdownd_client_free(lockdownClient);
- return result;
- }
-
- if (instproxy_client_new(m_device->device, lockdowndService,
- &instproxy) != INSTPROXY_E_SUCCESS) {
- result["error"] = "Could not connect to installation proxy.";
- lockdownd_service_descriptor_free(lockdowndService);
- lockdownd_client_free(lockdownClient);
- return result;
- }
-
- // The service descriptor is no longer needed after the client is
- // created
- lockdownd_service_descriptor_free(lockdowndService);
- lockdowndService = nullptr;
-
- plist_t client_opts = instproxy_client_options_new();
+ plist_t client_opts = plist_new_dict();
plist_dict_set_item(client_opts, "ApplicationType",
plist_new_string("User"));
@@ -456,56 +442,51 @@ void DiskUsageWidget::fetchData()
plist_new_string("DynamicDiskUsage"));
plist_dict_set_item(client_opts, "ReturnAttributes", return_attrs);
- plist_t apps = nullptr;
- if (instproxy_browse(instproxy, client_opts, &apps) ==
- INSTPROXY_E_SUCCESS &&
- apps) {
- if (plist_get_node_type(apps) == PLIST_ARRAY) {
- for (uint32_t i = 0; i < plist_array_get_size(apps); i++) {
- plist_t app_info = plist_array_get_item(apps, i);
- if (!app_info)
- continue;
+ auto apps_result = instproxy.browse(client_opts);
+ if (apps_result.is_ok()) {
+ auto apps = std::move(apps_result.unwrap());
+ for (const auto &app_info : apps) {
+ plist_t static_usage =
+ plist_dict_get_item(app_info, "StaticDiskUsage");
+ if (static_usage &&
+ plist_get_node_type(static_usage) == PLIST_UINT) {
+ uint64_t static_size = 0;
+ plist_get_uint_val(static_usage, &static_size);
+ totalAppsSpace += static_size;
+ }
- plist_t static_usage =
- plist_dict_get_item(app_info, "StaticDiskUsage");
- if (static_usage &&
- plist_get_node_type(static_usage) == PLIST_UINT) {
- uint64_t static_size = 0;
- plist_get_uint_val(static_usage, &static_size);
- totalAppsSpace += static_size;
- }
-
- plist_t dynamic_usage =
- plist_dict_get_item(app_info, "DynamicDiskUsage");
- if (dynamic_usage &&
- plist_get_node_type(dynamic_usage) == PLIST_UINT) {
- uint64_t dynamic_size = 0;
- plist_get_uint_val(dynamic_usage, &dynamic_size);
- totalAppsSpace += dynamic_size;
- }
+ plist_t dynamic_usage =
+ plist_dict_get_item(app_info, "DynamicDiskUsage");
+ if (dynamic_usage &&
+ plist_get_node_type(dynamic_usage) == PLIST_UINT) {
+ uint64_t dynamic_size = 0;
+ plist_get_uint_val(dynamic_usage, &dynamic_size);
+ totalAppsSpace += dynamic_size;
}
}
- plist_free(apps);
}
result["appsUsage"] = QVariant::fromValue(totalAppsSpace);
- plist_free(client_opts);
- instproxy_client_free(instproxy);
+ plist_free(client_opts); // client_opts is consumed by browse, but
// Media usage
uint64_t mediaSpace = 0;
- plist_t node = nullptr;
- if (lockdownd_get_value(lockdownClient, "com.apple.mobile.iTunes",
- nullptr, &node) == LOCKDOWN_E_SUCCESS &&
- node) {
- plist_t mediaNode = plist_dict_get_item(node, "MediaLibrarySize");
- if (mediaNode && plist_get_node_type(mediaNode) == PLIST_UINT) {
- plist_get_uint_val(mediaNode, &mediaSpace);
+ IdeviceFFI::Lockdown lockdown =
+ IdeviceFFI::Lockdown::adopt(m_device->lockdown);
+ auto itunes_info_res =
+ lockdown.get_value("com.apple.mobile.iTunes", nullptr);
+ if (itunes_info_res.is_ok()) {
+ auto itunes_dict = std::move(itunes_info_res.unwrap());
+ if (itunes_dict) {
+ plist_t media_node =
+ plist_dict_get_item(itunes_dict, "MediaLibrarySize");
+ if (media_node &&
+ plist_get_node_type(media_node) == PLIST_UINT) {
+ plist_get_uint_val(media_node, &mediaSpace);
+ }
}
- plist_free(node);
}
result["mediaUsage"] = QVariant::fromValue(mediaSpace);
- lockdownd_client_free(lockdownClient);
return result;
});
watcher->setFuture(future);
diff --git a/src/fileexplorerwidget.cpp b/src/fileexplorerwidget.cpp
index 32da91a..0b7c024 100644
--- a/src/fileexplorerwidget.cpp
+++ b/src/fileexplorerwidget.cpp
@@ -41,8 +41,6 @@
#include
#include
#include
-#include
-#include
FileExplorerWidget::FileExplorerWidget(iDescriptorDevice *device,
QWidget *parent)
diff --git a/src/fileexplorerwidget.h b/src/fileexplorerwidget.h
index a2eb418..7aa68d8 100644
--- a/src/fileexplorerwidget.h
+++ b/src/fileexplorerwidget.h
@@ -34,7 +34,6 @@
#include
#include
#include
-#include
class FileExplorerWidget : public QWidget
{
@@ -49,7 +48,7 @@ private slots:
private:
QSplitter *m_mainSplitter;
QStackedWidget *m_stackedWidget;
- afc_client_t currentAfcClient;
+ AfcClientHandle *currentAfcClient;
QTreeWidget *m_sidebarTree;
iDescriptorDevice *m_device;
diff --git a/src/iDescriptor.h b/src/iDescriptor.h
index defb1cf..cd89726 100644
--- a/src/iDescriptor.h
+++ b/src/iDescriptor.h
@@ -24,15 +24,20 @@
#include
#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-#include
-#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
#include
#include
#include
@@ -54,8 +59,11 @@
"https://raw.githubusercontent.com/iDescriptor/iDescriptor/refs/heads/" \
"main/DeveloperDiskImages.json"
-// This is because afc_read_directory accepts "/var/mobile/Media" as "/"
+// This is because afc_list_directory accepts "/var/mobile/Media" as "/"
#define POSSIBLE_ROOT "../../../../"
+#define IDEVICE_DEVICE_VERSION(maj, min, patch) \
+ ((((maj) & 0xFF) << 16) | (((min) & 0xFF) << 8) | ((patch) & 0xFF))
+#include "devicemonitor.h"
struct BatteryInfo {
QString health;
@@ -172,59 +180,62 @@ struct DeviceInfo {
std::string regionRaw;
std::string region;
unsigned int parsedDeviceVersion;
+ std::string wifiMacAddress;
};
struct iDescriptorDevice {
std::string udid;
- idevice_connection_type conn_type;
- idevice_t device;
+ DeviceMonitorThread::IdeviceConnectionType conn_type;
+ IdeviceProviderHandle *device;
DeviceInfo deviceInfo;
- afc_client_t afcClient;
- afc_client_t afc2Client;
+ AfcClientHandle *afcClient;
+ AfcClientHandle *afc2Client;
+ LockdowndClientHandle *lockdown;
bool is_iPhone;
std::recursive_mutex *mutex;
};
struct iDescriptorInitDeviceResult {
bool success = false;
- lockdownd_error_t error;
- idevice_t device;
+ IdeviceFfiError error;
+ IdeviceProviderHandle *device;
DeviceInfo deviceInfo;
- afc_client_t afcClient;
- afc_client_t afc2Client;
+ AfcClientHandle *afcClient;
+ AfcClientHandle *afc2Client;
+ LockdowndClientHandle *lockdown;
};
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-struct iDescriptorRecoveryDevice {
- uint64_t ecid;
- irecv_mode mode;
- uint32_t cpid;
- uint32_t bdid;
- std::string displayName;
- std::recursive_mutex *mutex;
-};
-#endif
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// struct iDescriptorRecoveryDevice {
+// uint64_t ecid;
+// irecv_mode mode;
+// uint32_t cpid;
+// uint32_t bdid;
+// std::string displayName;
+// std::recursive_mutex *mutex;
+// };
+// #endif
struct TakeScreenshotResult {
bool success = false;
QImage img;
};
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-struct iDescriptorInitDeviceResultRecovery {
- irecv_client_t client = nullptr;
- irecv_device_info deviceInfo;
- irecv_error_t error;
- bool success = false;
- irecv_mode mode = IRECV_K_RECOVERY_MODE_1;
- const char *displayName = nullptr;
-};
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// struct iDescriptorInitDeviceResultRecovery {
+// irecv_client_t client = nullptr;
+// irecv_device_info deviceInfo;
+// irecv_error_t error;
+// bool success = false;
+// irecv_mode mode = IRECV_K_RECOVERY_MODE_1;
+// const char *displayName = nullptr;
+// };
-#endif
+// #endif
void warn(const QString &message, const QString &title = "Warning",
QWidget *parent = nullptr);
-enum class AddType { Regular, Pairing };
+enum class AddType { Regular, Pairing, Wireless, UpgradeToWireless };
class PlistNavigator
{
@@ -293,14 +304,14 @@ public:
plist_t getNode() const { return current_node; }
};
-afc_error_t safe_afc_read_directory(afc_client_t afcClient, idevice_t device,
- const char *path, char ***dirs);
+// afc_error_t safe_afc_read_directory(afc_client_t afcClient, idevice_t device,
+// const char *path, char ***dirs);
std::string parse_product_type(const std::string &productType);
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-std::string parse_recovery_mode(irecv_mode productType);
-#endif
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// std::string parse_recovery_mode(irecv_mode productType);
+// #endif
struct MediaEntry {
std::string name;
@@ -313,114 +324,122 @@ struct AFCFileTree {
std::string currentPath;
};
-AFCFileTree get_file_tree(afc_client_t afcClient,
- const std::string &path = "/");
+// AFCFileTree get_file_tree(afc_client_t afcClient,
+// const std::string &path = "/");
-bool detect_jailbroken(afc_client_t afc);
+bool detect_jailbroken(AfcClientHandle *afc);
-void get_device_info_xml(const char *udid, lockdownd_client_t client,
- idevice_t device, pugi::xml_document &infoXml);
+void get_device_info_xml(const char *udid, LockdowndClientHandle *client,
+ pugi::xml_document &infoXml);
-iDescriptorInitDeviceResult init_idescriptor_device(const char *udid);
-
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-iDescriptorInitDeviceResultRecovery
-init_idescriptor_recovery_device(uint64_t ecid);
-#endif
-bool set_location(idevice_t device, char *lat, char *lon);
-
-bool shutdown(idevice_t device);
-
-TakeScreenshotResult take_screenshot(screenshotr_client_t shotr);
-
-mobile_image_mounter_error_t mount_dev_image(idevice_t device,
- unsigned int device_version,
- const char *image_dir_path);
-struct GetMountedImageResult {
- bool success;
- std::string sig;
- std::string message;
+struct WirelessInitArgs {
+ QString ip;
+ const IdevicePairingFile *pairing_file;
};
+iDescriptorInitDeviceResult
+init_idescriptor_device(const QString &udid,
+ WirelessInitArgs wirelessArgs = {nullptr, nullptr});
-plist_t _get_mounted_image(const char *udid);
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// iDescriptorInitDeviceResultRecovery
+// init_idescriptor_recovery_device(uint64_t ecid);
+// #endif
+// bool set_location(idevice_t device, char *lat, char *lon);
-bool restart(std::string udid);
+// bool shutdown(idevice_t device);
-enum class ImageCompatibility {
- Compatible, // Exact match or known compatible version
- MaybeCompatible, // Major version matches but minor doesn't
- NotCompatible // Not compatible
-};
+// TakeScreenshotResult take_screenshot(screenshotr_client_t shotr);
-struct ImageInfo {
- QString version;
- QString dmgPath;
- QString sigPath;
- ImageCompatibility compatibility = ImageCompatibility::NotCompatible;
- bool isDownloaded = false;
- bool isMounted = false;
-};
+// mobile_image_mounter_error_t mount_dev_image(idevice_t device,
+// unsigned int device_version,
+// const char *image_dir_path);
+// struct GetMountedImageResult {
+// bool success;
+// std::string sig;
+// std::string message;
+// };
-/**
- * @brief Compare two iPhone product types to determine which is newer
- * @param productType First iPhone product type (e.g., "iPhone8,1")
- * @param otherProductType Second iPhone product type (e.g., "iPhone7,2")
- * @return true if productType is newer than otherProductType, false otherwise
- *
- * Examples:
- * - compare_product_type("iPhone8,1", "iPhone7,2") returns true
- * - compare_product_type("iPhone6,1", "iPhone8,1") returns false
- * - compare_product_type("iPhone8,2", "iPhone8,1") returns true
- */
-bool compare_product_type(std::string productType,
- std::string otherProductType);
+// plist_t _get_mounted_image(const char *udid);
-/**
- * @brief Check if two iPhone product types are exactly equal
- * @param productType First iPhone product type
- * @param otherProductType Second iPhone product type
- * @return true if both product types are identical
- */
-bool are_product_types_equal(const std::string &productType,
- const std::string &otherProductType);
+// bool restart(std::string udid);
-/**
- * @brief Check if first product type is newer than second
- * @param productType First iPhone product type
- * @param otherProductType Second iPhone product type
- * @return true if productType is newer than otherProductType
- */
+// enum class ImageCompatibility {
+// Compatible, // Exact match or known compatible version
+// MaybeCompatible, // Major version matches but minor doesn't
+// NotCompatible // Not compatible
+// };
+
+// struct ImageInfo {
+// QString version;
+// QString dmgPath;
+// QString sigPath;
+// ImageCompatibility compatibility = ImageCompatibility::NotCompatible;
+// bool isDownloaded = false;
+// bool isMounted = false;
+// };
+
+// /**
+// * @brief Compare two iPhone product types to determine which is newer
+// * @param productType First iPhone product type (e.g., "iPhone8,1")
+// * @param otherProductType Second iPhone product type (e.g., "iPhone7,2")
+// * @return true if productType is newer than otherProductType, false
+// otherwise
+// *
+// * Examples:
+// * - compare_product_type("iPhone8,1", "iPhone7,2") returns true
+// * - compare_product_type("iPhone6,1", "iPhone8,1") returns false
+// * - compare_product_type("iPhone8,2", "iPhone8,1") returns true
+// */
+// bool compare_product_type(std::string productType,
+// std::string otherProductType);
+
+// /**
+// * @brief Check if two iPhone product types are exactly equal
+// * @param productType First iPhone product type
+// * @param otherProductType Second iPhone product type
+// * @return true if both product types are identical
+// */
+// bool are_product_types_equal(const std::string &productType,
+// const std::string &otherProductType);
+
+// /**
+// * @brief Check if first product type is newer than second
+// * @param productType First iPhone product type
+// * @param otherProductType Second iPhone product type
+// * @return true if productType is newer than otherProductType
+// */
bool is_product_type_newer(const std::string &productType,
const std::string &otherProductType);
-/**
- * @brief Check if first product type is older than second
- * @param productType First iPhone product type
- * @param otherProductType Second iPhone product type
- * @return true if productType is older than otherProductType
- */
-bool is_product_type_older(const std::string &productType,
- const std::string &otherProductType);
+// /**
+// * @brief Check if first product type is older than second
+// * @param productType First iPhone product type
+// * @param otherProductType Second iPhone product type
+// * @return true if productType is older than otherProductType
+// */
+// bool is_product_type_older(const std::string &productType,
+// const std::string &otherProductType);
-bool query_mobile_gestalt(iDescriptorDevice *id_device, const QStringList &keys,
- uint32_t &xml_size, char *&xml_data);
-;
+// bool query_mobile_gestalt(iDescriptorDevice *id_device, const QStringList
+// &keys,
+// uint32_t &xml_size, char *&xml_data);
+// ;
-std::string safeGetXML(const char *key, pugi::xml_node dict);
+// std::string safeGetXML(const char *key, pugi::xml_node dict);
-void get_battery_info(std::string productType, idevice_t idevice,
- bool is_iphone, plist_t &diagnostics);
+void get_battery_info(IdeviceProviderHandle *provider, plist_t &diagnostics);
-void parseOldDeviceBattery(PlistNavigator &ioreg, DeviceInfo &d);
-void parseDeviceBattery(PlistNavigator &ioreg, DeviceInfo &d);
+// void parseOldDeviceBattery(PlistNavigator &ioreg, DeviceInfo &d);
+// void parseDeviceBattery(PlistNavigator &ioreg, DeviceInfo &d);
-void fetchAppIconFromApple(QNetworkAccessManager *manager,
- const QString &bundleId,
- std::function callback);
+// void fetchAppIconFromApple(QNetworkAccessManager *manager,
+// const QString &bundleId,
+// std::function
+// callback);
-afc_error_t afc2_client_new(idevice_t device, afc_client_t *afc);
+// afc_error_t afc2_client_new(idevice_t device, afc_client_t *afc);
-void get_cable_info(idevice_t device, plist_t &response);
+// void get_cable_info(idevice_t device, plist_t &response);
struct NetworkDevice {
QString name; // service name
@@ -428,7 +447,7 @@ struct NetworkDevice {
QString address; // IPv4 or IPv6 address
uint16_t port = 22; // SSH port
std::map txt; // TXT records
-
+ QString macAddress; // MAC address if available
bool operator==(const NetworkDevice &other) const
{
return name == other.name && address == other.address;
@@ -437,13 +456,13 @@ struct NetworkDevice {
QPixmap load_heic(const QByteArray &data);
-QByteArray read_afc_file_to_byte_array(afc_client_t afcClient,
- const char *path);
+// QByteArray read_afc_file_to_byte_array(afc_client_t afcClient,
+// const char *path);
bool isDarkMode();
-instproxy_error_t install_IPA(idevice_t device, afc_client_t afc,
- const char *filePath);
+// instproxy_error_t install_IPA(idevice_t device, afc_client_t afc,
+// const char *filePath);
// Helper struct for semantic version comparison
struct AppVersion {
diff --git a/src/main.cpp b/src/main.cpp
index 7cb2815..e16ea84 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -18,7 +18,7 @@
*/
#include "mainwindow.h"
-#include "settingsmanager.h"
+// #include "settingsmanager.h"
#include
#include
#include
@@ -37,12 +37,12 @@ int main(int argc, char *argv[])
QCoreApplication::setApplicationName("iDescriptor");
QCoreApplication::setApplicationVersion(APP_VERSION);
- if (a.arguments().contains("--reset-settings")) {
- SettingsManager::sharedInstance()->clear();
- QMessageBox::information(nullptr, "Settings Reset",
- "All application settings have been reset to "
- "their default values.");
- }
+ // if (a.arguments().contains("--reset-settings")) {
+ // SettingsManager::sharedInstance()->clear();
+ // QMessageBox::information(nullptr, "Settings Reset",
+ // "All application settings have been reset to
+ // " "their default values.");
+ // }
#ifdef WIN32
QString appPath = QCoreApplication::applicationDirPath();
QString gstPluginPath =
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 6ccdcdc..ec28c5e 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -19,19 +19,19 @@
#include "mainwindow.h"
#include "./ui_mainwindow.h"
-#include "detailwindow.h"
-#include "ifusediskunmountbutton.h"
-#include "ifusemanager.h"
-#include "settingswidget.h"
+// #include "detailwindow.h"
+// #include "ifusediskunmountbutton.h"
+// #include "ifusemanager.h"
+// #include "settingswidget.h"
#include "appswidget.h"
#include "devicemanagerwidget.h"
#include "iDescriptor-ui.h"
#include "iDescriptor.h"
#include "jailbrokenwidget.h"
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-#include "libirecovery.h"
-#endif
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// #include "libirecovery.h"
+// #endif
#include "toolboxwidget.h"
#include "welcomewidget.h"
#include
@@ -42,90 +42,99 @@
#include
#include "appcontext.h"
-#include "settingsmanager.h"
+// #include "settingsmanager.h"
+// #include "devicemonitor.h"
+#include "networkdevicemanager.h"
+#include "networkdeviceswidget.h"
#include
#include
#include
#include
#include
-#ifdef WIN32
-#include "platform/windows/check_deps.h"
-#endif
+// #ifdef WIN32
+// #include "platform/windows/check_deps.h"
+// #endif
-void handleCallback(const idevice_event_t *event, void *userData)
-{
- printf("Device event received: ");
+using namespace IdeviceFFI;
- switch (event->event) {
- case IDEVICE_DEVICE_ADD: {
- /* this should never happen iDescriptor does not support network devices
- but for some reason even though we are only listening for USB devices,
- we still get network devices on macOS*/
- if (event->conn_type == CONNECTION_NETWORK) {
- return;
- }
- qDebug() << "Device added: " << QString::fromUtf8(event->udid);
+// void handleCallback(const idevice_event_t *event, void *userData)
+// {
+// printf("Device event received: ");
- QMetaObject::invokeMethod(
- AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection,
- Q_ARG(QString, QString::fromUtf8(event->udid)),
- Q_ARG(idevice_connection_type, event->conn_type),
- Q_ARG(AddType, AddType::Regular));
- break;
- }
+// switch (event->event) {
+// case IDEVICE_DEVICE_ADD: {
+// /* this should never happen iDescriptor does not support network
+// devices but for some reason even though we are only listening for USB
+// devices, we still get network devices on macOS*/ if (event->conn_type
+// == CONNECTION_NETWORK) {
+// return;
+// }
+// qDebug() << "Device added: " << QString::fromUtf8(event->udid);
- case IDEVICE_DEVICE_REMOVE: {
- QMetaObject::invokeMethod(AppContext::sharedInstance(), "removeDevice",
- Qt::QueuedConnection,
- Q_ARG(QString, QString(event->udid)));
- break;
- }
+// QMetaObject::invokeMethod(
+// AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection,
+// Q_ARG(QString, QString::fromUtf8(event->udid)),
+// Q_ARG(idevice_connection_type, event->conn_type),
+// Q_ARG(AddType, AddType::Regular));
+// break;
+// }
- case IDEVICE_DEVICE_PAIRED: {
- if (event->conn_type == CONNECTION_NETWORK) {
- qDebug()
- << "Network devices are not supported but a network device was "
- "received in event listener. Please report this issue.";
- return;
- }
- qDebug() << "Device paired: " << QString::fromUtf8(event->udid);
+// case IDEVICE_DEVICE_REMOVE: {
+// QMetaObject::invokeMethod(AppContext::sharedInstance(),
+// "removeDevice",
+// Qt::QueuedConnection,
+// Q_ARG(QString, QString(event->udid)));
+// break;
+// }
- QMetaObject::invokeMethod(
- AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection,
- Q_ARG(QString, QString::fromUtf8(event->udid)),
- Q_ARG(idevice_connection_type, event->conn_type),
- Q_ARG(AddType, AddType::Pairing));
- break;
- }
- default:
- qDebug() << "Unhandled event: " << event->event;
- }
-}
+// case IDEVICE_DEVICE_PAIRED: {
+// if (event->conn_type == CONNECTION_NETWORK) {
+// qDebug()
+// << "Network devices are not supported but a network device
+// was "
+// "received in event listener. Please report this issue.";
+// return;
+// }
+// qDebug() << "Device paired: " << QString::fromUtf8(event->udid);
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-void handleCallbackRecovery(const irecv_device_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(AddType, AddType::Pairing));
+// break;
+// }
+// default:
+// qDebug() << "Unhandled event: " << event->event;
+// }
+// }
- switch (event->type) {
- case IRECV_DEVICE_ADD:
- qDebug() << "Recovery device added: ";
- QMetaObject::invokeMethod(AppContext::sharedInstance(),
- "addRecoveryDevice", Qt::QueuedConnection,
- Q_ARG(uint64_t, event->device_info->ecid));
- break;
- case IRECV_DEVICE_REMOVE:
- qDebug() << "Recovery device removed: ";
- QMetaObject::invokeMethod(AppContext::sharedInstance(),
- "removeRecoveryDevice", Qt::QueuedConnection,
- Q_ARG(uint64_t, event->device_info->ecid));
- break;
- default:
- printf("Unhandled recovery event: %d\n", event->type);
- }
-}
-irecv_device_event_context_t context;
-#endif
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// void handleCallbackRecovery(const irecv_device_event_t *event, void
+// *userData)
+// {
+
+// switch (event->type) {
+// case IRECV_DEVICE_ADD:
+// qDebug() << "Recovery device added: ";
+// QMetaObject::invokeMethod(AppContext::sharedInstance(),
+// "addRecoveryDevice", Qt::QueuedConnection,
+// Q_ARG(uint64_t, event->device_info->ecid));
+// break;
+// case IRECV_DEVICE_REMOVE:
+// qDebug() << "Recovery device removed: ";
+// QMetaObject::invokeMethod(AppContext::sharedInstance(),
+// "removeRecoveryDevice",
+// Qt::QueuedConnection, Q_ARG(uint64_t,
+// event->device_info->ecid));
+// break;
+// default:
+// printf("Unhandled recovery event: %d\n", event->type);
+// }
+// }
+// irecv_device_event_context_t context;
+// #endif
MainWindow *MainWindow::sharedInstance()
{
@@ -162,27 +171,32 @@ MainWindow::MainWindow(QWidget *parent)
this, &MainWindow::updateNoDevicesConnected);
m_ZTabWidget->addTab(m_mainStackedWidget, "iDevice");
- auto *appsWidgetTab =
- m_ZTabWidget->addTab(AppsWidget::sharedInstance(), "Apps");
- m_ZTabWidget->addTab(new ToolboxWidget(this), "Toolbox");
+ // auto *appsWidgetTab =
+ // m_ZTabWidget->addTab(AppsWidget::sharedInstance(), "Apps");
+ // m_ZTabWidget->addTab(new ToolboxWidget(this), "Toolbox");
+ m_ZTabWidget->addTab(new QWidget(), "Apps"); // Placeholder for Apps tab
+ m_ZTabWidget->addTab(new QWidget(),
+ "Toolbox"); // Placeholder for Toolbox tab
+ m_ZTabWidget->addTab(new QWidget(),
+ "Jailbroken"); // Placeholder for Jailbroken tab
- auto *jailbrokenWidget = new JailbrokenWidget(this);
- m_ZTabWidget->addTab(jailbrokenWidget, "Jailbroken");
+ // auto *jailbrokenWidget = new JailbrokenWidget(this);
+ // m_ZTabWidget->addTab(jailbrokenWidget, "Jailbroken");
m_ZTabWidget->finalizeStyles();
- connect(
- appsWidgetTab, &ZTab::clicked, this,
- [this](int index) { AppsWidget::sharedInstance()->init(); },
- Qt::SingleShotConnection);
+ // connect(
+ // appsWidgetTab, &ZTab::clicked, this,
+ // [this](int index) { AppsWidget::sharedInstance()->init(); },
+ // Qt::SingleShotConnection);
- // settings button
- ZIconWidget *settingsButton = new ZIconWidget(
- QIcon(":/resources/icons/MingcuteSettings7Line.png"), "Settings");
- settingsButton->setCursor(Qt::PointingHandCursor);
- settingsButton->setFixedSize(24, 24);
- connect(settingsButton, &ZIconWidget::clicked, this, [this]() {
- SettingsManager::sharedInstance()->showSettingsDialog();
- });
+ // // settings button
+ // ZIconWidget *settingsButton = new ZIconWidget(
+ // QIcon(":/resources/icons/MingcuteSettings7Line.png"), "Settings");
+ // settingsButton->setCursor(Qt::PointingHandCursor);
+ // settingsButton->setFixedSize(24, 24);
+ // connect(settingsButton, &ZIconWidget::clicked, this, [this]() {
+ // SettingsManager::sharedInstance()->showSettingsDialog();
+ // });
ZIconWidget *githubButton = new ZIconWidget(
QIcon(":/resources/icons/MdiGithub.png"), "iDescriptor on GitHub");
@@ -204,57 +218,62 @@ MainWindow::MainWindow(QWidget *parent)
"QLabel:hover { background-color : #13131319; }");
ui->statusbar->addPermanentWidget(appVersionLabel);
ui->statusbar->addPermanentWidget(githubButton);
- ui->statusbar->addPermanentWidget(settingsButton);
+ // ui->statusbar->addPermanentWidget(settingsButton);
-#ifdef __linux__
- QList mounted_iFusePaths = iFuseManager::getMountPoints();
+ // #ifdef __linux__
+ // QList mounted_iFusePaths = iFuseManager::getMountPoints();
- for (const QString &path : mounted_iFusePaths) {
- auto *p = new iFuseDiskUnmountButton(path);
+ // for (const QString &path : mounted_iFusePaths) {
+ // auto *p = new iFuseDiskUnmountButton(path);
- ui->statusbar->addPermanentWidget(p);
- connect(p, &iFuseDiskUnmountButton::clicked, this, [this, p, path]() {
- bool ok = iFuseManager::linuxUnmount(path);
- if (!ok) {
- QMessageBox::warning(nullptr, "Unmount Failed",
- "Failed to unmount iFuse at " + path +
- ". Please try again.");
- return;
- }
- ui->statusbar->removeWidget(p);
- p->deleteLater();
- });
- }
-#endif
+ // ui->statusbar->addPermanentWidget(p);
+ // connect(p, &iFuseDiskUnmountButton::clicked, this, [this, p,
+ // path]() {
+ // bool ok = iFuseManager::linuxUnmount(path);
+ // if (!ok) {
+ // QMessageBox::warning(nullptr, "Unmount Failed",
+ // "Failed to unmount iFuse at " + path
+ // +
+ // ". Please try again.");
+ // return;
+ // }
+ // ui->statusbar->removeWidget(p);
+ // p->deleteLater();
+ // });
+ // }
+ // #endif
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- irecv_error_t res_recovery =
- irecv_device_event_subscribe(&context, handleCallbackRecovery, nullptr);
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // irecv_error_t res_recovery =
+ // irecv_device_event_subscribe(&context, handleCallbackRecovery,
+ // nullptr);
- if (res_recovery != IRECV_E_SUCCESS) {
- qDebug() << "ERROR: Unable to subscribe to recovery device events. "
- "Error code:"
- << res_recovery;
- }
- qDebug() << "Subscribed to recovery device events successfully.";
-#endif
+ // if (res_recovery != IRECV_E_SUCCESS) {
+ // qDebug() << "ERROR: Unable to subscribe to recovery device
+ // events. "
+ // "Error code:"
+ // << res_recovery;
+ // }
+ // qDebug() << "Subscribed to recovery device events successfully.";
+ // #endif
- idevice_error_t res = idevice_event_subscribe(handleCallback, nullptr);
- if (res != IDEVICE_E_SUCCESS) {
- qDebug() << "ERROR: Unable to subscribe to device events. Error code:"
- << res;
- }
- qDebug() << "Subscribed to device events successfully.";
- createMenus();
+ // idevice_error_t res = idevice_event_subscribe(handleCallback,
+ // nullptr); if (res != IDEVICE_E_SUCCESS) {
+ // qDebug() << "ERROR: Unable to subscribe to device events. Error
+ // code:"
+ // << res;
+ // }
+ // qDebug() << "Subscribed to device events successfully.";
+ // createMenus();
- UpdateProcedure updateProcedure;
- bool packageManagerManaged = false;
- bool isPortable = false;
- bool skipPrerelease = true;
-#ifdef WIN32
- isPortable = !is_iDescriptorInstalled();
- qDebug() << "isPortable=" << isPortable;
-#endif
+ // UpdateProcedure updateProcedure;
+ // bool packageManagerManaged = false;
+ // bool isPortable = false;
+ // bool skipPrerelease = true;
+ // #ifdef WIN32
+ // isPortable = !is_iDescriptorInstalled();
+ // qDebug() << "isPortable=" << isPortable;
+ // #endif
/*
struct UpdateProcedure {
@@ -265,71 +284,225 @@ MainWindow::MainWindow(QWidget *parent)
QString boxText;
};
*/
- switch (ZUpdater::detectPlatform()) {
- case Platform::Windows:
- updateProcedure = UpdateProcedure{
- !isPortable,
- isPortable,
- !isPortable,
- isPortable ? "New portable version downloaded, app location will "
- "be shown after this message"
- : "The application will now quit to install the update.",
- isPortable ? "New portable version downloaded"
- : "Do you want to install the downloaded update now?",
- };
- break;
- // todo: adjust for pkg managers
- case Platform::MacOS:
- updateProcedure = UpdateProcedure{
- true,
- false,
- true,
- "The application will now quit and open .dmg file downloaded to "
- "\"Downloads\" from there you can drag it to Applications to "
- "install.",
- "Update downloaded would you like to quit and install the update?",
- };
- break;
- case Platform::Linux:
- // currently only on linux (arch aur) is enabled
-#ifdef PACKAGE_MANAGER_MANAGED
- packageManagerManaged = true;
-#endif
- updateProcedure = UpdateProcedure{
- true,
- false,
- true,
- "AppImages we ship are not updateable. New version is downloaded "
- "to "
- "\"Downloads\". You can start using the new version by launching "
- "it "
- "from there. You can delete this AppImage version if you like.",
- "Update downloaded would you like to quit and open the new "
- "version?",
- };
- break;
- default:
- updateProcedure = UpdateProcedure{
- false, false, false, "", "",
- };
- }
+ // switch (ZUpdater::detectPlatform()) {
+ // case Platform::Windows:
+ // updateProcedure = UpdateProcedure{
+ // !isPortable,
+ // isPortable,
+ // !isPortable,
+ // isPortable ? "New portable version downloaded, app location
+ // will "
+ // "be shown after this message"
+ // : "The application will now quit to install the
+ // update.",
+ // isPortable ? "New portable version downloaded"
+ // : "Do you want to install the downloaded update
+ // now?",
+ // };
+ // break;
+ // // todo: adjust for pkg managers
+ // case Platform::MacOS:
+ // updateProcedure = UpdateProcedure{
+ // true,
+ // false,
+ // true,
+ // "The application will now quit and open .dmg file downloaded
+ // to "
+ // "\"Downloads\" from there you can drag it to Applications to
+ // " "install.", "Update downloaded would you like to quit and
+ // install the update?",
+ // };
+ // break;
+ // case Platform::Linux:
+ // // currently only on linux (arch aur) is enabled
+ // #ifdef PACKAGE_MANAGER_MANAGED
+ // packageManagerManaged = true;
+ // #endif
+ // updateProcedure = UpdateProcedure{
+ // true,
+ // false,
+ // true,
+ // "AppImages we ship are not updateable. New version is
+ // downloaded " "to "
+ // "\"Downloads\". You can start using the new version by
+ // launching " "it " "from there. You can delete this AppImage
+ // version if you like.", "Update downloaded would you like to
+ // quit and open the new " "version?",
+ // };
+ // break;
+ // default:
+ // updateProcedure = UpdateProcedure{
+ // false, false, false, "", "",
+ // };
+ // }
- m_updater = new ZUpdater("iDescriptor/iDescriptor", APP_VERSION,
- "iDescriptor", updateProcedure, isPortable,
- packageManagerManaged, skipPrerelease, this);
-#if defined(PACKAGE_MANAGER_MANAGED) && defined(__linux__)
- m_updater->setPackageManagerManagedMessage(
- QString(
- "You seem to have installed iDescriptor using a package manager. "
- "Please use %1 to update it.")
- .arg(PACKAGE_MANAGER_HINT));
-#endif
+ // m_updater = new ZUpdater("iDescriptor/iDescriptor", APP_VERSION,
+ // "iDescriptor", updateProcedure, isPortable,
+ // packageManagerManaged, skipPrerelease,
+ // this);
+ // #if defined(PACKAGE_MANAGER_MANAGED) && defined(__linux__)
+ // m_updater->setPackageManagerManagedMessage(
+ // QString(
+ // "You seem to have installed iDescriptor using a package
+ // manager. " "Please use %1 to update it.")
+ // .arg(PACKAGE_MANAGER_HINT));
+ // #endif
- SettingsManager::sharedInstance()->doIfEnabled(
- SettingsManager::Setting::AutoCheckUpdates, [this]() {
- qDebug() << "Checking for updates...";
- m_updater->checkForUpdates();
+ // SettingsManager::sharedInstance()->doIfEnabled(
+ // SettingsManager::Setting::AutoCheckUpdates, [this]() {
+ // qDebug() << "Checking for updates...";
+ // m_updater->checkForUpdates();
+ // });
+
+ // Usage in main thread:
+ m_deviceMonitor = new DeviceMonitorThread(this);
+ connect(
+ m_deviceMonitor, &DeviceMonitorThread::deviceEvent, this,
+ [this](int event, const QString &udid, int conn_type, int addType) {
+ // Handle device connection
+ switch (event) {
+ case DeviceMonitorThread::IDEVICE_DEVICE_ADD: {
+ /* this should never happen iDescriptor does not
+ support network devices but for some reason even
+ though we are only listening for USB devices, we
+ still get network devices on macOS*/
+ if (conn_type == DeviceMonitorThread::CONNECTION_NETWORK) {
+ return;
+ }
+ qDebug() << "Device added: " << udid;
+
+ QMetaObject::invokeMethod(
+ AppContext::sharedInstance(), "addDevice",
+ Qt::QueuedConnection, Q_ARG(QString, udid),
+ Q_ARG(
+ DeviceMonitorThread::IdeviceConnectionType,
+ static_cast(
+ conn_type)),
+ Q_ARG(AddType, AddType::Regular));
+ break;
+ }
+
+ case DeviceMonitorThread::IDEVICE_DEVICE_REMOVE: {
+ QMetaObject::invokeMethod(AppContext::sharedInstance(),
+ "removeDevice", Qt::QueuedConnection,
+ Q_ARG(QString, udid));
+ break;
+ }
+
+ case DeviceMonitorThread::IDEVICE_DEVICE_PAIRED: {
+ if (conn_type == DeviceMonitorThread::CONNECTION_NETWORK) {
+ qDebug() << "Network devices are not supported but a "
+ "network device was "
+ "received in event listener. Please report "
+ "this issue.";
+ return;
+ }
+ qDebug() << "Device paired: " << udid;
+
+ QMetaObject::invokeMethod(
+ AppContext::sharedInstance(), "addDevice",
+ Qt::QueuedConnection, Q_ARG(QString, udid),
+ Q_ARG(
+ DeviceMonitorThread::IdeviceConnectionType,
+ static_cast(
+ conn_type)),
+ Q_ARG(AddType, AddType::Pairing));
+ break;
+ }
+ default:
+ qDebug() << "Unhandled event: " << event;
+ }
});
+
+ m_deviceMonitor->start();
+
+ connect(AppContext::sharedInstance(), &AppContext::deviceRemoved, this,
+ [](const std::string &udid, const std::string &wifiMacAddress) {
+ const IdevicePairingFile *pairingFile =
+ AppContext::sharedInstance()->getCachedPairingFile(
+ QString::fromStdString(udid));
+
+ if (pairingFile) {
+ // qDebug() << "Device removed, pairing file for UDID"
+ // << QString::fromStdString(udid) << "MAC"
+ // << QString::fromStdString(wifiMacAddress)
+ // << "exists in cache.";
+ // try to upgrade device to wireless if possible
+ qDebug()
+ << "Upgrading device to wireless connection for UDID"
+ << QString::fromStdString(udid);
+ QMetaObject::invokeMethod(
+ AppContext::sharedInstance(), "addDevice",
+ Qt::QueuedConnection,
+ Q_ARG(QString, QString::fromStdString(udid)),
+ Q_ARG(DeviceMonitorThread::IdeviceConnectionType,
+ DeviceMonitorThread::CONNECTION_NETWORK),
+ Q_ARG(AddType, AddType::UpgradeToWireless),
+ Q_ARG(QString, QString::fromStdString(wifiMacAddress)));
+
+ } else {
+ qDebug()
+ << "Device removed, no cached pairing file for UDID"
+ << QString::fromStdString(udid);
+ }
+ });
+
+ connect(NetworkDeviceManager::sharedInstance(),
+ &NetworkDeviceManager::deviceAdded, this,
+ [this](const NetworkDevice &device) {
+ // const iDescriptorDevice *idevice =
+ // AppContext::sharedInstance()->getDeviceByMacAddress(
+ // device.macAddress);
+ // if (idevice) {
+ // qDebug() << "Network device matched to connected device:"
+ // << QString::fromStdString(
+ // idevice->deviceInfo.deviceName)
+ // << "MAC:" << device.macAddress;
+ // // You can now use 'idevice' as needed
+ // }
+ // FIXME: both macAddress and udid can be used to get pairing
+ // file
+
+ if (AppContext::sharedInstance()->getDeviceByMacAddress(
+ device.macAddress)) {
+ qDebug() << "Prefering wired connection on device MAC:"
+ << device.macAddress;
+ return;
+ }
+
+ const IdevicePairingFile *pairingFile =
+ AppContext::sharedInstance()->getCachedPairingFile(
+ device.macAddress);
+
+ if (!pairingFile) {
+ qDebug() << "No cached pairing file for network device MAC:"
+ << device.macAddress
+ << "Cannot add as wireless device.";
+ return;
+ }
+
+ qDebug() << "Trying to add network device with MAC:"
+ << device.macAddress;
+
+ QMetaObject::invokeMethod(
+ AppContext::sharedInstance(), "addDevice",
+ Qt::QueuedConnection, Q_ARG(QString, device.macAddress),
+ Q_ARG(DeviceMonitorThread::IdeviceConnectionType,
+ DeviceMonitorThread::CONNECTION_NETWORK),
+ Q_ARG(AddType, AddType::Wireless),
+ Q_ARG(QString, device.macAddress));
+
+ // Handle network device addition if needed
+ });
+
+ // NetworkDevicesWidget *m_networkDevicesWidget = new
+ // NetworkDevicesWidget();
+ // m_networkDevicesWidget->setAttribute(Qt::WA_DeleteOnClose);
+ // m_networkDevicesWidget->setWindowFlag(Qt::Window);
+ // m_networkDevicesWidget->resize(500, 600);
+ // // connect(m_networkDevicesWidget, &QObject::destroyed, this,
+ // // [this]() { m_networkDevicesWidget = nullptr; });
+ // m_networkDevicesWidget->show();
}
void MainWindow::createMenus()
@@ -339,9 +512,9 @@ void MainWindow::createMenus()
QAction *aboutAct = new QAction("&About iDescriptor", this);
connect(aboutAct, &QAction::triggered, this, [this]() {
- QMessageBox::about(
- this, "iDescriptor",
- "A free, open-source, and cross-platform iDevice management tool.");
+ QMessageBox::about(this, "iDescriptor",
+ "A free, open-source, and cross-platform "
+ "iDevice management tool.");
});
actionsMenu->addAction(aboutAct);
#endif
@@ -357,19 +530,23 @@ void MainWindow::updateNoDevicesConnected()
return m_mainStackedWidget->setCurrentIndex(0); // Show Welcome page
}
int deviceCount = AppContext::sharedInstance()->getConnectedDeviceCount();
- m_connectedDeviceCountLabel->setText(
- "iDescriptor: " + QString::number(deviceCount) +
- (deviceCount == 1 ? " device" : " devices") + " connected");
+ // m_connectedDeviceCountLabel->setText(
+ // "iDescriptor: " + QString::number(deviceCount) +
+ // (deviceCount == 1 ? " device" : " devices") + " connected");
m_mainStackedWidget->setCurrentIndex(1); // Show device list page
}
MainWindow::~MainWindow()
{
- idevice_event_unsubscribe();
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
- irecv_device_event_unsubscribe(context);
-#endif
+ // idevice_event_unsubscribe();
+ // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+ // irecv_device_event_unsubscribe(context);
+ // #endif
delete ui;
- delete m_updater;
- sleep(2);
+ m_deviceMonitor->requestInterruption();
+ // FIXME:QThread: Destroyed while thread '' is still running
+ // m_deviceMonitor->wait();
+ delete m_deviceMonitor;
+ // delete m_updater;
+ // sleep(2);
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index db2938c..85d1bbb 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -23,12 +23,13 @@
#include "ZUpdater.h"
#include "devicemanagerwidget.h"
#include "iDescriptor.h"
-#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
-#include "libirecovery.h"
-#endif
+#include
+// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
+// #include "libirecovery.h"
+// #endif
+#include "devicemonitor.h"
#include "ztabwidget.h"
#include
-#include
#include
QT_BEGIN_NAMESPACE
@@ -58,5 +59,6 @@ private:
DeviceManagerWidget *m_deviceManager;
QStackedWidget *m_mainStackedWidget;
QLabel *m_connectedDeviceCountLabel;
+ DeviceMonitorThread *m_deviceMonitor;
};
#endif // MAINWINDOW_H
diff --git a/src/networkdevicemanager.cpp b/src/networkdevicemanager.cpp
new file mode 100644
index 0000000..1177fb8
--- /dev/null
+++ b/src/networkdevicemanager.cpp
@@ -0,0 +1,28 @@
+#include "networkdevicemanager.h"
+
+NetworkDeviceManager *NetworkDeviceManager::sharedInstance()
+{
+ static NetworkDeviceManager instance;
+ return &instance;
+}
+
+NetworkDeviceManager::NetworkDeviceManager(QObject *parent) : QObject{parent}
+{
+
+#ifdef __linux__
+ m_networkProvider = new AvahiService(this);
+ connect(m_networkProvider, &AvahiService::deviceAdded, this,
+ &NetworkDeviceManager::deviceAdded);
+ connect(m_networkProvider, &AvahiService::deviceRemoved, this,
+ &NetworkDeviceManager::deviceRemoved);
+#else
+ m_networkProvider = new DnssdService(this);
+ connect(m_networkProvider, &DnssdService::deviceAdded, this,
+ &NetworkDeviceManager::deviceAdded);
+ connect(m_networkProvider, &DnssdService::deviceRemoved, this,
+ &NetworkDeviceManager::deviceRemoved);
+#endif
+
+ // Start scanning for network devices
+ m_networkProvider->startBrowsing();
+}
diff --git a/src/networkdevicemanager.h b/src/networkdevicemanager.h
new file mode 100644
index 0000000..5dfab9b
--- /dev/null
+++ b/src/networkdevicemanager.h
@@ -0,0 +1,29 @@
+#ifndef NETWORKDEVICEMANAGER_H
+#define NETWORKDEVICEMANAGER_H
+
+#include
+
+#ifdef __linux__
+#include "core/services/avahi/avahi_service.h"
+#else
+#include "core/services/dnssd/dnssd_service.h"
+#endif
+
+class NetworkDeviceManager : public QObject
+{
+ Q_OBJECT
+public:
+ explicit NetworkDeviceManager(QObject *parent = nullptr);
+
+#ifdef __linux__
+ AvahiService *m_networkProvider = nullptr;
+#else
+ DnssdService *m_networkProvider = nullptr;
+#endif
+ static NetworkDeviceManager *sharedInstance();
+signals:
+ void deviceAdded(const NetworkDevice &device);
+ void deviceRemoved(const QString &deviceName);
+};
+
+#endif // NETWORKDEVICEMANAGER_H