mirror of
https://github.com/iDescriptor/iDescriptor.git
synced 2026-06-21 19:35:49 +08:00
implement interval to try connecting to wireless devices and add device sleep warning dialog
This commit is contained in:
@@ -76,6 +76,7 @@
|
||||
<file>resources/keychain.mp4</file>
|
||||
<file>resources/wireless-gallery-import.mp4</file>
|
||||
<file>resources/dev-mode.mp4</file>
|
||||
<file>resources/unlock.mp4</file>
|
||||
<file>resources/trust.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
Executable
BIN
Binary file not shown.
+16
-4
@@ -181,6 +181,12 @@ void AppContext::removeDevice(iDescriptor::Uniq uniq, bool ask_backend)
|
||||
auto device = m_devices[q_udid];
|
||||
m_devices.remove(q_udid);
|
||||
|
||||
qDebug() << "Removed device with UUID " + q_udid << "macAddress:"
|
||||
<< QString::fromStdString(device->deviceInfo.wifiMacAddress)
|
||||
<< "ipAddress:"
|
||||
<< QString::fromStdString(device->deviceInfo.ipAddress)
|
||||
<< "wasWireless:" << device->deviceInfo.isWireless;
|
||||
|
||||
emit deviceRemoved(q_udid, device->deviceInfo.wifiMacAddress,
|
||||
device->deviceInfo.ipAddress,
|
||||
device->deviceInfo.isWireless);
|
||||
@@ -350,13 +356,17 @@ void AppContext::heartbeatFailed(const QString &macAddress, int tries)
|
||||
emit deviceHeartbeatFailed(macAddress, tries);
|
||||
}
|
||||
|
||||
void AppContext::tryToConnectToNetworkDevice(const NetworkDevice &device)
|
||||
void AppContext::tryToConnectToNetworkDevice(const NetworkDevice &device,
|
||||
bool forceCache,
|
||||
bool setSelectionIfExists)
|
||||
{
|
||||
qDebug() << "Trying to connect to network device with MAC:"
|
||||
<< device.macAddress << "IP:" << device.address;
|
||||
|
||||
// force refresh macAddress-pairing file mapping
|
||||
cachePairedDevices();
|
||||
if (forceCache) {
|
||||
cachePairedDevices();
|
||||
}
|
||||
|
||||
const iDescriptorDevice *existingDevice = nullptr;
|
||||
existingDevice = getDeviceByMacAddress(device.macAddress);
|
||||
@@ -365,8 +375,10 @@ void AppContext::tryToConnectToNetworkDevice(const NetworkDevice &device)
|
||||
emit deviceAlreadyExistsMAC(
|
||||
iDescriptor::Uniq(existingDevice->deviceInfo.wifiMacAddress, true));
|
||||
// TODO: add a setting for this
|
||||
|
||||
setCurrentDeviceSelection(DeviceSelection(existingDevice->udid), true);
|
||||
if (setSelectionIfExists) {
|
||||
setCurrentDeviceSelection(DeviceSelection(existingDevice->udid),
|
||||
true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -45,7 +45,9 @@ public:
|
||||
const QString getCachedPairingFile(const QString &udid) const;
|
||||
CXX::Core *core = new CXX::Core(this);
|
||||
CXX::IOManager *ioManager = new CXX::IOManager(this);
|
||||
void tryToConnectToNetworkDevice(const NetworkDevice &device);
|
||||
void tryToConnectToNetworkDevice(const NetworkDevice &device,
|
||||
bool forceCache = true,
|
||||
bool setSelectionIfExists = true);
|
||||
#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
|
||||
QList<iDescriptorRecoveryDevice *> getAllRecoveryDevices();
|
||||
#endif
|
||||
|
||||
@@ -70,12 +70,12 @@ DeviceManagerWidget::DeviceManagerWidget(QWidget *parent)
|
||||
connect(AppContext::sharedInstance(), &AppContext::devicePaired, this,
|
||||
[this](const std::shared_ptr<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));
|
||||
});
|
||||
|
||||
updateUI();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "devicesleepwarningwidget.h"
|
||||
|
||||
DeviceSleepWarningWidget::DeviceSleepWarningWidget(QWidget *parent)
|
||||
: QDialog{parent}
|
||||
{
|
||||
#ifdef WIN32
|
||||
setupWinWindow(this);
|
||||
#endif
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(0, 20, 0, 0);
|
||||
mainLayout->setSpacing(0);
|
||||
|
||||
m_loadingWidget = new ZLoadingWidget(false, this);
|
||||
mainLayout->addWidget(m_loadingWidget);
|
||||
|
||||
QWidget *contentContainer = new QWidget(this);
|
||||
QVBoxLayout *contentLayout = new QVBoxLayout(contentContainer);
|
||||
contentLayout->setContentsMargins(0, 0, 0, 0);
|
||||
contentLayout->setSpacing(0);
|
||||
m_loadingWidget->setupContentWidget(contentContainer);
|
||||
|
||||
m_mediaPlayer = new QMediaPlayer(this);
|
||||
m_videoWidget = new QVideoWidget(this);
|
||||
m_videoWidget->setMinimumSize(300, 500);
|
||||
m_videoWidget->setSizePolicy(QSizePolicy::Expanding,
|
||||
QSizePolicy::Expanding);
|
||||
m_videoWidget->setAspectRatioMode(Qt::KeepAspectRatio);
|
||||
m_mediaPlayer->setVideoOutput(m_videoWidget);
|
||||
|
||||
connect(m_mediaPlayer,
|
||||
QOverload<QMediaPlayer::MediaStatus>::of(
|
||||
&QMediaPlayer::mediaStatusChanged),
|
||||
[this](QMediaPlayer::MediaStatus status) {
|
||||
if (status == QMediaPlayer::EndOfMedia) {
|
||||
m_mediaPlayer->setPosition(0);
|
||||
m_mediaPlayer->play();
|
||||
}
|
||||
});
|
||||
|
||||
QLabel *title = new QLabel("Keep Your Device Awake", this);
|
||||
title->setAlignment(Qt::AlignCenter);
|
||||
title->setStyleSheet("QLabel { font-size: 18px; font-weight: bold; }");
|
||||
|
||||
QLabel *description = new QLabel(
|
||||
R"(Please keep your device awake or unlocked while connected wirelessly to avoid disconnection)",
|
||||
this);
|
||||
description->setAlignment(Qt::AlignCenter);
|
||||
description->setWordWrap(true);
|
||||
|
||||
QVBoxLayout *textLayout = new QVBoxLayout();
|
||||
textLayout->setContentsMargins(20, 20, 20, 20);
|
||||
textLayout->setSpacing(10);
|
||||
contentLayout->addWidget(title);
|
||||
textLayout->addWidget(description);
|
||||
|
||||
contentLayout->addLayout(textLayout);
|
||||
contentLayout->addWidget(m_videoWidget);
|
||||
|
||||
contentLayout->addSpacing(20);
|
||||
|
||||
QCheckBox *dontShowAgain = new QCheckBox("Don't show this again", this);
|
||||
connect(dontShowAgain, &QCheckBox::toggled, this, [this](bool checked) {
|
||||
SettingsManager::sharedInstance()->setIsSleepyDeviceWarningDismissed(
|
||||
checked);
|
||||
});
|
||||
|
||||
contentLayout->addWidget(dontShowAgain, 0, Qt::AlignCenter);
|
||||
m_mediaPlayer->setSource(QUrl("qrc:/resources/unlock.mp4"));
|
||||
QTimer::singleShot(500, this, &DeviceSleepWarningWidget::init);
|
||||
}
|
||||
|
||||
void DeviceSleepWarningWidget::init()
|
||||
{
|
||||
m_mediaPlayer->play();
|
||||
m_loadingWidget->stop();
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef DEVICESLEEPWARNINGWIDGET_H
|
||||
#define DEVICESLEEPWARNINGWIDGET_H
|
||||
|
||||
#include "iDescriptor-ui.h"
|
||||
#include "iDescriptor.h"
|
||||
#include "zloadingwidget.h"
|
||||
#include <QCheckBox>
|
||||
#include <QDialog>
|
||||
#include <QMediaPlayer>
|
||||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
#include <QVideoWidget>
|
||||
#include <QWidget>
|
||||
|
||||
class DeviceSleepWarningWidget : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeviceSleepWarningWidget(QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
ZLoadingWidget *m_loadingWidget;
|
||||
QMediaPlayer *m_mediaPlayer;
|
||||
QVideoWidget *m_videoWidget;
|
||||
|
||||
void init();
|
||||
};
|
||||
|
||||
#endif // DEVICESLEEPWARNINGWIDGET_H
|
||||
+30
-12
@@ -26,23 +26,13 @@
|
||||
#include "releasechangelogdialog.h"
|
||||
#include "toolboxwidget.h"
|
||||
#include "welcomewidget.h"
|
||||
#include <QHBoxLayout>
|
||||
#include <QStack>
|
||||
#include <QStackedWidget>
|
||||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "appcontext.h"
|
||||
#include "networkdeviceswidget.h"
|
||||
#include "settingsmanager.h"
|
||||
#include "statusballoon.h"
|
||||
#include <QApplication>
|
||||
#include <QDesktopServices>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "platform/windows/win_common.h"
|
||||
#endif
|
||||
@@ -129,11 +119,16 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
auto mainLayout = new QVBoxLayout(centralWidget);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
connect(AppContext::sharedInstance()->core, &CXX::Core::device_event, this,
|
||||
auto core = AppContext::sharedInstance()->core;
|
||||
|
||||
connect(core, &CXX::Core::device_event, this,
|
||||
[this](uint32_t code, const QString &udid, const QString &info) {
|
||||
handleCallback(code, udid, info);
|
||||
});
|
||||
|
||||
connect(core, &CXX::Core::sleepy_time_detected, this,
|
||||
&MainWindow::handleShowSleepyDeviceWarning);
|
||||
|
||||
AppContext::sharedInstance()->core->init();
|
||||
|
||||
m_ZTabWidget = new ZTabWidget(this);
|
||||
@@ -491,4 +486,27 @@ MainWindow::~MainWindow()
|
||||
#endif
|
||||
delete m_updater;
|
||||
// sleep(2);
|
||||
}
|
||||
|
||||
void MainWindow::handleShowSleepyDeviceWarning()
|
||||
{
|
||||
|
||||
/* one minute cooldown to prevent spamming */
|
||||
static const int kMinIntervalMs = 60 * 1000;
|
||||
|
||||
static QDateTime lastShown;
|
||||
const auto now = QDateTime::currentDateTimeUtc();
|
||||
|
||||
if (lastShown.isValid() && lastShown.msecsTo(now) < kMinIntervalMs) {
|
||||
qDebug() << "Ignoring sleepy device warning dialog.";
|
||||
return;
|
||||
}
|
||||
|
||||
lastShown = now;
|
||||
|
||||
if (SettingsManager::sharedInstance()->isSleepyDeviceWarningDismissed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceSleepWarningWidget(this).exec();
|
||||
}
|
||||
@@ -21,13 +21,25 @@
|
||||
#define MAINWINDOW_H
|
||||
#include "ZDownloader.h"
|
||||
#include "ZUpdater.h"
|
||||
#include "devicesleepwarningwidget.h"
|
||||
#include "iDescriptor-ui.h"
|
||||
#include "iDescriptor.h"
|
||||
#include "iomanagerclient.h"
|
||||
#include "ztabwidget.h"
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QDesktopServices>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QStack>
|
||||
#include <QStackedWidget>
|
||||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class DeviceManagerWidget;
|
||||
|
||||
@@ -43,6 +55,7 @@ public:
|
||||
void raiseDeviceTab();
|
||||
void showConnectedDevicesTab();
|
||||
void showWelcomeTab();
|
||||
void handleShowSleepyDeviceWarning();
|
||||
public slots:
|
||||
void updateNoDevicesConnected();
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
NetworkDeviceCard::NetworkDeviceCard(const NetworkDevice &device,
|
||||
QWidget *parent)
|
||||
: QWidget(parent)
|
||||
: QWidget(parent), m_device(device)
|
||||
{
|
||||
QVBoxLayout *cardLayout = new QVBoxLayout(this);
|
||||
cardLayout->setContentsMargins(12, 10, 12, 10);
|
||||
@@ -182,6 +182,12 @@ NetworkDevicesToConnectWidget::NetworkDevicesToConnectWidget(QWidget *parent)
|
||||
&NetworkDevicesToConnectWidget::onDeviceAdded);
|
||||
connect(AppContext::sharedInstance(), &AppContext::deviceAlreadyExistsMAC,
|
||||
this, &NetworkDevicesToConnectWidget::onDeviceAlreadyExists);
|
||||
|
||||
// eval interval
|
||||
QTimer *evalTimer = new QTimer(this);
|
||||
connect(evalTimer, &QTimer::timeout, this,
|
||||
&NetworkDevicesToConnectWidget::eval);
|
||||
evalTimer->start(30000); // evaluate every 30 seconds
|
||||
}
|
||||
|
||||
NetworkDevicesToConnectWidget::~NetworkDevicesToConnectWidget() {}
|
||||
@@ -313,6 +319,21 @@ void NetworkDevicesToConnectWidget::onWirelessDeviceRemoved(
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkDevicesToConnectWidget::eval()
|
||||
{
|
||||
if (QCoreApplication::closingDown())
|
||||
return;
|
||||
bool forceCache = true;
|
||||
for (const auto &card : m_deviceCards) {
|
||||
if (card) {
|
||||
NetworkDevice device = card->getDevice();
|
||||
AppContext::sharedInstance()->tryToConnectToNetworkDevice(
|
||||
device, forceCache, false);
|
||||
forceCache = false; // force cache once
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkDevicesToConnectWidget::onNoPairingFileForWirelessDevice(
|
||||
const QString &macAddress)
|
||||
{
|
||||
@@ -367,4 +388,4 @@ void NetworkDevicesToConnectWidget::onDeviceAlreadyExists(
|
||||
return;
|
||||
}
|
||||
qDebug() << "No device card found for" << uniq.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
|
||||
private:
|
||||
QPushButton *m_connectButton = nullptr;
|
||||
NetworkDevice m_device;
|
||||
|
||||
public:
|
||||
void failed();
|
||||
@@ -46,6 +47,7 @@ public:
|
||||
void initStarted();
|
||||
void connected();
|
||||
void alreadyExists();
|
||||
NetworkDevice getDevice() { return m_device; };
|
||||
};
|
||||
|
||||
class NetworkDevicesToConnectWidget : public QWidget
|
||||
@@ -70,7 +72,7 @@ private:
|
||||
void createDeviceCard(const NetworkDevice &device);
|
||||
void clearDeviceCards();
|
||||
void updateDeviceList();
|
||||
|
||||
void eval();
|
||||
QGroupBox *m_deviceGroup = nullptr;
|
||||
QScrollArea *m_scrollArea = nullptr;
|
||||
QWidget *m_scrollContent = nullptr;
|
||||
|
||||
@@ -306,7 +306,10 @@ impl qobject::HauseArrest {
|
||||
true
|
||||
});
|
||||
if !inserted {
|
||||
eprintln!("start_video_stream: failed to insert video stream for udid={} path={}", udid_str, cloned_path);
|
||||
eprintln!(
|
||||
"start_video_stream: failed to insert video stream for udid={} path={}",
|
||||
udid_str, cloned_path
|
||||
);
|
||||
return QString::default();
|
||||
}
|
||||
eprintln!(
|
||||
|
||||
+31
-7
@@ -1,13 +1,12 @@
|
||||
use futures::StreamExt;
|
||||
use idevice::{
|
||||
IdeviceService,
|
||||
IdeviceError, IdeviceService,
|
||||
afc::AfcClient,
|
||||
diagnostics_relay::DiagnosticsRelayClient,
|
||||
heartbeat,
|
||||
lockdown::LockdownClient,
|
||||
pairing_file::PairingFile,
|
||||
provider::{TcpProvider},
|
||||
IdeviceError,
|
||||
provider::TcpProvider,
|
||||
usbmuxd::{Connection, UsbmuxdAddr, UsbmuxdConnection, UsbmuxdListenEvent},
|
||||
};
|
||||
use std::{any::type_name, sync::Arc};
|
||||
@@ -29,8 +28,8 @@ use crate::qobject::Core;
|
||||
use once_cell::sync::Lazy;
|
||||
use plist::Value;
|
||||
mod afc;
|
||||
mod afc_services;
|
||||
mod afc2_services;
|
||||
mod afc_services;
|
||||
mod hause_arrest;
|
||||
mod io_manager;
|
||||
mod screenshot;
|
||||
@@ -55,7 +54,6 @@ pub struct DeviceServices {
|
||||
pub lockdown: Arc<Mutex<LockdownClient>>,
|
||||
}
|
||||
|
||||
|
||||
pub static APP_DEVICE_STATE: Lazy<Mutex<HashMap<String, DeviceServices>>> =
|
||||
Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
|
||||
@@ -122,6 +120,9 @@ mod qobject {
|
||||
|
||||
#[qsignal]
|
||||
fn no_pairing_file(self: Pin<&mut Core>, mac_address: &QString);
|
||||
|
||||
#[qsignal]
|
||||
fn sleepy_time_detected(self: Pin<&mut Core>);
|
||||
}
|
||||
impl cxx_qt::Threading for Core {}
|
||||
}
|
||||
@@ -638,7 +639,7 @@ async fn init_idescriptor_device<
|
||||
return None;
|
||||
}
|
||||
let mut hb = None;
|
||||
|
||||
|
||||
if is_wireless {
|
||||
eprintln!("init_idescriptor_device: Attempting to connect to HeartbeatClient.");
|
||||
hb = match heartbeat::HeartbeatClient::connect(&provider).await {
|
||||
@@ -735,7 +736,6 @@ async fn init_idescriptor_device<
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
eprintln!("init_idescriptor_device: Storing device services.");
|
||||
let device_services = DeviceServices {
|
||||
afc: Arc::new(Mutex::new(afc_client)),
|
||||
@@ -810,6 +810,19 @@ async fn spawn_heartbeat_task(
|
||||
Err(e) => {
|
||||
fails += 1;
|
||||
eprintln!("heartbeat: get_marco failed (fail count: {fails}): {e:?}");
|
||||
|
||||
match e {
|
||||
IdeviceError::Heartbeat(idevice::HeartbeatError::SleepyTime) => {
|
||||
println!("heartbeat: Sleepy time");
|
||||
qt_thread
|
||||
.queue(move |core_qobj| {
|
||||
core_qobj.sleepy_time_detected();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
if fails >= 3 {
|
||||
eprintln!("heartbeat: too many failures for giving up");
|
||||
clean_device_from_app_state(&udid_for_hb).await;
|
||||
@@ -832,6 +845,17 @@ async fn spawn_heartbeat_task(
|
||||
if let Err(e) = hb_client.send_polo().await {
|
||||
fails += 1;
|
||||
eprintln!("heartbeat: send_polo failed (fail count: {fails}): {e:?}");
|
||||
match e {
|
||||
IdeviceError::Heartbeat(idevice::HeartbeatError::SleepyTime) => {
|
||||
println!("heartbeat: Sleepy time");
|
||||
qt_thread
|
||||
.queue(move |core_qobj| {
|
||||
core_qobj.sleepy_time_detected();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
if fails >= 3 {
|
||||
eprintln!("heartbeat: too many failures for , giving up");
|
||||
clean_device_from_app_state(&udid_for_hb).await;
|
||||
|
||||
@@ -75,7 +75,7 @@ mod qobject {
|
||||
);
|
||||
|
||||
#[qsignal]
|
||||
fn dev_image_mounted(self: Pin<&mut ServiceManager>, success: bool,is_locked: bool);
|
||||
fn dev_image_mounted(self: Pin<&mut ServiceManager>, success: bool, is_locked: bool);
|
||||
|
||||
#[qsignal]
|
||||
fn developer_mode_option_revealed(self: Pin<&mut ServiceManager>, success: bool);
|
||||
@@ -131,7 +131,6 @@ mod qobject {
|
||||
#[qsignal]
|
||||
fn install_ipa_progress(self: Pin<&mut ServiceManager>, progress: f64, state: QString);
|
||||
|
||||
|
||||
#[qinvokable]
|
||||
fn enable_wifi_connections(&self);
|
||||
|
||||
@@ -908,11 +907,7 @@ impl qobject::ServiceManager {
|
||||
let udid = self.get_udid().to_string();
|
||||
|
||||
run_sync(async move {
|
||||
let maybe_device = APP_DEVICE_STATE
|
||||
.lock()
|
||||
.await
|
||||
.get(udid.as_str())
|
||||
.cloned();
|
||||
let maybe_device = APP_DEVICE_STATE.lock().await.get(udid.as_str()).cloned();
|
||||
|
||||
let device = match maybe_device {
|
||||
Some(d) => d,
|
||||
@@ -924,7 +919,7 @@ impl qobject::ServiceManager {
|
||||
|
||||
if let Err(e) = device.diag.lock().await.restart().await {
|
||||
eprintln!("restart: Failed to restart device {udid}: {e}");
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
@@ -934,11 +929,7 @@ impl qobject::ServiceManager {
|
||||
let udid = self.get_udid().to_string();
|
||||
|
||||
run_sync(async move {
|
||||
let maybe_device = APP_DEVICE_STATE
|
||||
.lock()
|
||||
.await
|
||||
.get(udid.as_str())
|
||||
.cloned();
|
||||
let maybe_device = APP_DEVICE_STATE.lock().await.get(udid.as_str()).cloned();
|
||||
|
||||
let device = match maybe_device {
|
||||
Some(d) => d,
|
||||
@@ -950,7 +941,7 @@ impl qobject::ServiceManager {
|
||||
|
||||
if let Err(e) = device.diag.lock().await.shutdown().await {
|
||||
eprintln!("shutdown: Failed to shutdown device {udid}: {e}");
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
@@ -959,11 +950,7 @@ impl qobject::ServiceManager {
|
||||
let udid = self.get_udid().to_string();
|
||||
|
||||
run_sync(async move {
|
||||
let maybe_device = APP_DEVICE_STATE
|
||||
.lock()
|
||||
.await
|
||||
.get(udid.as_str())
|
||||
.cloned();
|
||||
let maybe_device = APP_DEVICE_STATE.lock().await.get(udid.as_str()).cloned();
|
||||
|
||||
let device = match maybe_device {
|
||||
Some(d) => d,
|
||||
@@ -974,8 +961,10 @@ impl qobject::ServiceManager {
|
||||
};
|
||||
|
||||
if let Err(e) = device.lockdown.lock().await.enter_recovery().await {
|
||||
eprintln!("enter_recovery_mode: Failed to enter recovery mode for device {udid}: {e}");
|
||||
return false
|
||||
eprintln!(
|
||||
"enter_recovery_mode: Failed to enter recovery mode for device {udid}: {e}"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
@@ -985,8 +974,15 @@ impl qobject::ServiceManager {
|
||||
let udid = self.get_udid().to_string();
|
||||
let qt_t = self.qt_thread();
|
||||
let local_ipa_path_owned = local_ipa_path.clone().to_string();
|
||||
// FIXME: this is a bit hacky
|
||||
let ipa_path_on_device = format!("/PublicStaging/{}", local_ipa_path.to_string().split('/').last().unwrap_or("app.ipa"));
|
||||
// FIXME: this is a bit hacky
|
||||
let ipa_path_on_device = format!(
|
||||
"/PublicStaging/{}",
|
||||
local_ipa_path
|
||||
.to_string()
|
||||
.split('/')
|
||||
.last()
|
||||
.unwrap_or("app.ipa")
|
||||
);
|
||||
RUNTIME.spawn(async move {
|
||||
let qt_thread = qt_t.clone();
|
||||
|
||||
@@ -1145,24 +1141,21 @@ impl qobject::ServiceManager {
|
||||
let qt_t = self.qt_thread();
|
||||
let udid = self.get_udid().to_string();
|
||||
|
||||
|
||||
RUNTIME.spawn(async move {
|
||||
let qt_thread = qt_t.clone();
|
||||
|
||||
|
||||
let lc_arc = {
|
||||
let maybe_device = APP_DEVICE_STATE
|
||||
.lock()
|
||||
.await
|
||||
.get(udid.as_str())
|
||||
.cloned();
|
||||
let maybe_device = APP_DEVICE_STATE.lock().await.get(udid.as_str()).cloned();
|
||||
|
||||
let device = match maybe_device {
|
||||
Some(d) => d,
|
||||
None => {
|
||||
eprintln!("enable_wifi_connections: device {udid} not found");
|
||||
let _ = qt_thread.queue(|t| {
|
||||
t.enable_wifi_connections_result(false);
|
||||
}).ok();
|
||||
let _ = qt_thread
|
||||
.queue(|t| {
|
||||
t.enable_wifi_connections_result(false);
|
||||
})
|
||||
.ok();
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -1173,22 +1166,31 @@ impl qobject::ServiceManager {
|
||||
let mut lc = lc_arc.lock().await;
|
||||
|
||||
let value = Value::Boolean(true);
|
||||
match lc.set_value("EnableWifiConnections", value, Some("com.apple.mobile.wireless_lockdown")).await {
|
||||
match lc
|
||||
.set_value(
|
||||
"EnableWifiConnections",
|
||||
value,
|
||||
Some("com.apple.mobile.wireless_lockdown"),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => {
|
||||
let _ = qt_thread.queue(|t| {
|
||||
t.enable_wifi_connections_result(true);
|
||||
}).ok();
|
||||
},
|
||||
let _ = qt_thread
|
||||
.queue(|t| {
|
||||
t.enable_wifi_connections_result(true);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("wireless: LockdownClient::set_value failed: {e:?}");
|
||||
let _ = qt_thread.queue(|t| {
|
||||
t.enable_wifi_connections_result(false);
|
||||
}).ok();
|
||||
let _ = qt_thread
|
||||
.queue(|t| {
|
||||
t.enable_wifi_connections_result(false);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1202,21 +1204,21 @@ async fn set_device_location_lockdown(
|
||||
}
|
||||
|
||||
// iOS 17+:
|
||||
async fn set_device_location_rsd(
|
||||
proxy: CoreDeviceProxy,
|
||||
latitude: f64,
|
||||
longitude: f64,
|
||||
) -> Result<(), idevice::IdeviceError> {
|
||||
async fn set_device_location_rsd(
|
||||
proxy: CoreDeviceProxy,
|
||||
latitude: f64,
|
||||
longitude: f64,
|
||||
) -> Result<(), idevice::IdeviceError> {
|
||||
let rsd_port = proxy.tunnel_info().server_rsd_port;
|
||||
let adapter = proxy.create_software_tunnel()?;
|
||||
let mut adapter = adapter.to_async_handle();
|
||||
let stream = adapter.connect(rsd_port).await?;
|
||||
|
||||
let mut handshake = RsdHandshake::new(stream).await?;
|
||||
|
||||
let mut remote_server = RemoteServerClient::connect_rsd(&mut adapter, &mut handshake).await?;
|
||||
remote_server.read_message(0).await?;
|
||||
|
||||
let mut location_client = LocationSimulationClient::new(&mut remote_server).await?;
|
||||
location_client.set(latitude, longitude).await
|
||||
}
|
||||
let adapter = proxy.create_software_tunnel()?;
|
||||
let mut adapter = adapter.to_async_handle();
|
||||
let stream = adapter.connect(rsd_port).await?;
|
||||
|
||||
let mut handshake = RsdHandshake::new(stream).await?;
|
||||
|
||||
let mut remote_server = RemoteServerClient::connect_rsd(&mut adapter, &mut handshake).await?;
|
||||
remote_server.read_message(0).await?;
|
||||
|
||||
let mut location_client = LocationSimulationClient::new(&mut remote_server).await?;
|
||||
location_client.set(latitude, longitude).await
|
||||
}
|
||||
|
||||
+19
-1
@@ -265,6 +265,7 @@ void SettingsManager::resetToDefaults()
|
||||
#ifdef __linux__
|
||||
setShowV4L2(false);
|
||||
#endif
|
||||
setIsSleepyDeviceWarningDismissed(false);
|
||||
}
|
||||
|
||||
void SettingsManager::saveFavoritePlace(const QString &path,
|
||||
@@ -502,4 +503,21 @@ WIN_BACKDROP SettingsManager::winBackdropType() const
|
||||
return static_cast<WIN_BACKDROP>(
|
||||
m_settings->value("winBackdropType", static_cast<int>(MICA)).toInt());
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool SettingsManager::isSleepyDeviceWarningDismissed() const
|
||||
{
|
||||
return m_settings->value("sleepyDeviceWarningDismissed", false).toBool();
|
||||
}
|
||||
|
||||
void SettingsManager::dismissSleepyDeviceWarning()
|
||||
{
|
||||
m_settings->setValue("sleepyDeviceWarningDismissed", true);
|
||||
m_settings->sync();
|
||||
}
|
||||
|
||||
void SettingsManager::setIsSleepyDeviceWarningDismissed(bool dismissed)
|
||||
{
|
||||
m_settings->setValue("sleepyDeviceWarningDismissed", dismissed);
|
||||
m_settings->sync();
|
||||
}
|
||||
@@ -138,6 +138,11 @@ public:
|
||||
void setWinBackdropType(WIN_BACKDROP type);
|
||||
WIN_BACKDROP winBackdropType() const;
|
||||
#endif
|
||||
|
||||
bool isSleepyDeviceWarningDismissed() const;
|
||||
void setIsSleepyDeviceWarningDismissed(bool dismissed);
|
||||
void dismissSleepyDeviceWarning();
|
||||
|
||||
signals:
|
||||
void favoritePlacesChanged();
|
||||
void recentLocationsChanged();
|
||||
|
||||
Reference in New Issue
Block a user