diff --git a/QtScrcpy/QtScrcpy.pro b/QtScrcpy/QtScrcpy.pro index 865f7c1..96c590d 100644 --- a/QtScrcpy/QtScrcpy.pro +++ b/QtScrcpy/QtScrcpy.pro @@ -41,6 +41,7 @@ include ($$PWD/uibase/uibase.pri) include ($$PWD/fontawesome/fontawesome.pri) include ($$PWD/util/util.pri) include ($$PWD/device/device.pri) +include ($$PWD/devicemanage/devicemanage.pri) # 附加包含路径 INCLUDEPATH += \ @@ -48,7 +49,8 @@ INCLUDEPATH += \ $$PWD/adb \ $$PWD/uibase \ $$PWD/util \ - $$PWD/device \ + $$PWD/device \ + $$PWD/devicemanage \ $$PWD/fontawesome diff --git a/QtScrcpy/device/device.cpp b/QtScrcpy/device/device.cpp index af4140f..e2e668f 100644 --- a/QtScrcpy/device/device.cpp +++ b/QtScrcpy/device/device.cpp @@ -9,6 +9,7 @@ #include "filehandler.h" #include "stream.h" #include "videoform.h" +#include "controller.h" Device::Device(DeviceParams params, QObject *parent) : QObject(parent) @@ -69,6 +70,7 @@ Device::~Device() if (m_videoForm) { delete m_videoForm; } + emit deviceDisconnect(m_params.serial); } VideoForm *Device::getVideoForm() @@ -81,6 +83,11 @@ Controller *Device::getController() return m_controller; } +Server *Device::getServer() +{ + return m_server; +} + void Device::initSignals() { if (m_controller && m_videoForm) { diff --git a/QtScrcpy/device/device.h b/QtScrcpy/device/device.h index afcef19..8697df3 100644 --- a/QtScrcpy/device/device.h +++ b/QtScrcpy/device/device.h @@ -4,8 +4,6 @@ #include #include -#include "controller.h" - class Recorder; class Server; class VideoBuffer; @@ -13,6 +11,7 @@ class Decoder; class FileHandler; class Stream; class VideoForm; +class Controller; class Device : public QObject { Q_OBJECT @@ -32,6 +31,10 @@ public: VideoForm *getVideoForm(); Controller *getController(); + Server *getServer(); + +signals: + void deviceDisconnect(QString serial); private: void initSignals(); diff --git a/QtScrcpy/device/server/server.cpp b/QtScrcpy/device/server/server.cpp index ce3823a..a7017c9 100644 --- a/QtScrcpy/device/server/server.cpp +++ b/QtScrcpy/device/server/server.cpp @@ -168,6 +168,16 @@ bool Server::connectTo() return true; } +bool Server::isReverse() +{ + return !m_tunnelForward; +} + +Server::ServerParams Server::getParams() +{ + return m_params; +} + void Server::timerEvent(QTimerEvent *event) { if (event && m_acceptTimeoutTimer == event->timerId()) { diff --git a/QtScrcpy/device/server/server.h b/QtScrcpy/device/server/server.h index 6ccee1f..6d6fda1 100644 --- a/QtScrcpy/device/server/server.h +++ b/QtScrcpy/device/server/server.h @@ -38,6 +38,8 @@ public: bool start(Server::ServerParams params); bool connectTo(); + bool isReverse(); + Server::ServerParams getParams(); VideoSocket* getVideoSocket(); QTcpSocket* getControlSocket(); diff --git a/QtScrcpy/devicemanage/devicemanage.cpp b/QtScrcpy/devicemanage/devicemanage.cpp new file mode 100644 index 0000000..de2d2fa --- /dev/null +++ b/QtScrcpy/devicemanage/devicemanage.cpp @@ -0,0 +1,87 @@ +#include + +#include "devicemanage.h" +#include "server.h" + +#define DM_MAX_DEVICES_NUM 16 + +DeviceManage::DeviceManage(QObject *parent) : QObject(parent) +{ + +} + +DeviceManage::~DeviceManage() +{ + +} + +bool DeviceManage::connectDevice(Device::DeviceParams params) +{ + if (params.serial.trimmed().isEmpty()) { + return false; + } + if (m_devices.contains(params.serial)) { + return false; + } + if (DM_MAX_DEVICES_NUM < m_devices.size()) { + qInfo("over the maximum number of connections"); + return false; + } + quint16 port = 0; + if (params.useReverse) { + port = getFreePort(); + if (0 == port) { + qInfo("no port available, automatically switch to forward"); + params.useReverse = false; + } else { + qInfo("free port %d", port); + } + } + Device *device = new Device(params); + connect(device, &Device::deviceDisconnect, this, &DeviceManage::onDeviceDisconnect); + m_devices[params.serial] = device; + return true; +} + +bool DeviceManage::disconnectDevice(const QString &serial) +{ + bool ret = false; + if (!serial.isEmpty() && m_devices.contains(serial)) { + auto it = m_devices.find(serial); + if (it->data()) { + it->data()->deleteLater(); + ret = true; + } + } + return ret; +} + +void DeviceManage::onDeviceDisconnect(QString serial) +{ + if (!serial.isEmpty() && m_devices.contains(serial)) { + m_devices.remove(serial); + } +} + +quint16 DeviceManage::getFreePort() +{ + quint16 port = m_localPortStart; + QMapIterator> i(m_devices); + while (port < m_localPortStart + DM_MAX_DEVICES_NUM) { + bool used = false; + while (i.hasNext()) { + i.next(); + auto device = i.value(); + if (device && device->getServer() + && device->getServer()->isReverse() + && port == device->getServer()->getParams().localPort) { + used = true; + break; + } + } + if (!used) { + return port; + } + } + return 0; +} diff --git a/QtScrcpy/devicemanage/devicemanage.h b/QtScrcpy/devicemanage/devicemanage.h new file mode 100644 index 0000000..e45bfdf --- /dev/null +++ b/QtScrcpy/devicemanage/devicemanage.h @@ -0,0 +1,30 @@ +#ifndef DEVICEMANAGE_H +#define DEVICEMANAGE_H + +#include +#include + +#include "device.h" + +class DeviceManage : public QObject +{ + Q_OBJECT +public: + explicit DeviceManage(QObject *parent = nullptr); + virtual ~DeviceManage(); + + bool connectDevice(Device::DeviceParams params); + bool disconnectDevice(const QString &serial); + +protected slots: + void onDeviceDisconnect(QString serial); + +private: + quint16 getFreePort(); + +private: + QMap> m_devices; + quint16 m_localPortStart = 27183; +}; + +#endif // DEVICEMANAGE_H diff --git a/QtScrcpy/devicemanage/devicemanage.pri b/QtScrcpy/devicemanage/devicemanage.pri new file mode 100644 index 0000000..8b2ff86 --- /dev/null +++ b/QtScrcpy/devicemanage/devicemanage.pri @@ -0,0 +1,5 @@ +HEADERS += \ + $$PWD/devicemanage.h + +SOURCES += \ + $$PWD/devicemanage.cpp diff --git a/QtScrcpy/dialog.cpp b/QtScrcpy/dialog.cpp index 95181aa..6aeaea9 100644 --- a/QtScrcpy/dialog.cpp +++ b/QtScrcpy/dialog.cpp @@ -102,42 +102,42 @@ void Dialog::on_updateDevice_clicked() void Dialog::on_startServerBtn_clicked() { - if (!m_device) { - outLog("start server...", false); + outLog("start server...", false); - QString absFilePath; - QString fileDir(ui->recordPathEdt->text().trimmed()); - if (!fileDir.isEmpty()) { - QDateTime dateTime = QDateTime::currentDateTime(); - QString fileName = dateTime.toString("_yyyyMMdd_hhmmss_zzz"); - QString ext = ui->formatBox->currentText().trimmed(); - fileName = windowTitle() + fileName + "." + ext; - QDir dir(fileDir); - absFilePath = dir.absoluteFilePath(fileName); - } + QString absFilePath; + QString fileDir(ui->recordPathEdt->text().trimmed()); + if (!fileDir.isEmpty()) { + QDateTime dateTime = QDateTime::currentDateTime(); + QString fileName = dateTime.toString("_yyyyMMdd_hhmmss_zzz"); + QString ext = ui->formatBox->currentText().trimmed(); + fileName = windowTitle() + fileName + "." + ext; + QDir dir(fileDir); + absFilePath = dir.absoluteFilePath(fileName); + } - quint32 bitRate = ui->bitRateBox->currentText().trimmed().toUInt(); - // this is ok that "native" toUshort is 0 - quint16 videoSize = ui->videoSizeBox->currentText().trimmed().toUShort(); - Device::DeviceParams params; - params.serial = ui->serialBox->currentText().trimmed(); - params.maxSize = videoSize; - params.bitRate = bitRate; - params.recordFileName = absFilePath; - params.closeScreen = ui->closeScreenCheck->isChecked(); - params.useReverse = ui->useReverseCheck->isChecked(); - params.display = !ui->notDisplayCheck->isChecked(); - m_device = new Device(params, this); + quint32 bitRate = ui->bitRateBox->currentText().trimmed().toUInt(); + // this is ok that "native" toUshort is 0 + quint16 videoSize = ui->videoSizeBox->currentText().trimmed().toUShort(); + Device::DeviceParams params; + params.serial = ui->serialBox->currentText().trimmed(); + params.maxSize = videoSize; + params.bitRate = bitRate; + params.recordFileName = absFilePath; + params.closeScreen = ui->closeScreenCheck->isChecked(); + params.useReverse = ui->useReverseCheck->isChecked(); + params.display = !ui->notDisplayCheck->isChecked(); + m_deviceManage.connectDevice(params); + +/* if (ui->alwaysTopCheck->isChecked() && m_device->getVideoForm()) { m_device->getVideoForm()->staysOnTop(); - } - } + } + */ } void Dialog::on_stopServerBtn_clicked() { - if (m_device) { - m_device->deleteLater(); + if (m_deviceManage.disconnectDevice(ui->serialBox->currentText().trimmed())) { outLog("stop server"); } } @@ -257,10 +257,6 @@ void Dialog::on_stopAdbBtn_clicked() } void Dialog::on_clearOut_clicked() -{ - static bool show = true; - m_adb.setShowTouchesEnabled("", show); - show = !show; - +{ ui->outEdit->clear(); } diff --git a/QtScrcpy/dialog.h b/QtScrcpy/dialog.h index 6215c21..6536f08 100644 --- a/QtScrcpy/dialog.h +++ b/QtScrcpy/dialog.h @@ -5,12 +5,12 @@ #include #include "adbprocess.h" +#include "devicemanage.h" namespace Ui { class Dialog; } -class Device; class QYUVOpenGLWidget; class Dialog : public QDialog { @@ -55,7 +55,7 @@ private: private: Ui::Dialog *ui; AdbProcess m_adb; - QPointer m_device; + DeviceManage m_deviceManage; }; #endif // DIALOG_H