From 447b15e7b66894605ecaf464502df840baf257f4 Mon Sep 17 00:00:00 2001 From: Lasan Mahaliyana Date: Sat, 28 Feb 2026 21:25:22 +0530 Subject: [PATCH] removed old tray app code --- sharing/linux/qml_tray_app/CMakeLists.txt | 34 - sharing/linux/qml_tray_app/Main.qml | 858 ------------ sharing/linux/qml_tray_app/README.md | 17 +- sharing/linux/qml_tray_app/main.cpp | 143 -- .../qml_tray_app/nearby_tray_controller.cc | 1213 ----------------- .../qml_tray_app/nearby_tray_controller.h | 204 --- sharing/linux/qml_tray_app/resources.qrc | 9 - 7 files changed, 9 insertions(+), 2469 deletions(-) delete mode 100644 sharing/linux/qml_tray_app/Main.qml delete mode 100644 sharing/linux/qml_tray_app/main.cpp delete mode 100644 sharing/linux/qml_tray_app/nearby_tray_controller.cc delete mode 100644 sharing/linux/qml_tray_app/nearby_tray_controller.h delete mode 100644 sharing/linux/qml_tray_app/resources.qrc diff --git a/sharing/linux/qml_tray_app/CMakeLists.txt b/sharing/linux/qml_tray_app/CMakeLists.txt index b3b03cb0..518fbf44 100644 --- a/sharing/linux/qml_tray_app/CMakeLists.txt +++ b/sharing/linux/qml_tray_app/CMakeLists.txt @@ -49,13 +49,6 @@ set_target_properties( INTERFACE_INCLUDE_DIRECTORIES "${NEARBY_FACADE_INCLUDE_ROOT}" ) -qt_add_executable(nearby_qml_tray_app - main.cpp - nearby_tray_controller.cc - nearby_tray_controller.h - resources.qrc -) - qt_add_executable(nearby_qml_file_tray_app file_share_tray_main.cpp file_share_tray_controller.cc @@ -63,20 +56,6 @@ qt_add_executable(nearby_qml_file_tray_app resources_file_share.qrc ) -target_include_directories(nearby_qml_tray_app PRIVATE - "${CMAKE_CURRENT_LIST_DIR}" - "${NEARBY_FACADE_INCLUDE_ROOT}" -) -target_link_libraries(nearby_qml_tray_app PRIVATE - Qt6::Core - Qt6::Gui - Qt6::Widgets - Qt6::Qml - Qt6::Quick - Qt6::QuickControls2 - nearby_connections_service_linux_installed -) - target_include_directories(nearby_qml_file_tray_app PRIVATE "${CMAKE_CURRENT_LIST_DIR}" "${NEARBY_FACADE_INCLUDE_ROOT}" @@ -93,18 +72,11 @@ target_link_libraries(nearby_qml_file_tray_app PRIVATE get_filename_component(NEARBY_CONNECTIONS_SHARED_LIB_DIR "${NEARBY_CONNECTIONS_SHARED_LIB}" DIRECTORY) -set_target_properties(nearby_qml_tray_app PROPERTIES - BUILD_RPATH "${NEARBY_CONNECTIONS_SHARED_LIB_DIR}" - INSTALL_RPATH "$ORIGIN" -) set_target_properties(nearby_qml_file_tray_app PROPERTIES BUILD_RPATH "${NEARBY_CONNECTIONS_SHARED_LIB_DIR}" INSTALL_RPATH "$ORIGIN" ) -install(TARGETS nearby_qml_tray_app - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" -) install(TARGETS nearby_qml_file_tray_app RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" ) @@ -113,12 +85,6 @@ install(FILES "${NEARBY_CONNECTIONS_SHARED_LIB}" DESTINATION "${CMAKE_INSTALL_BINDIR}" ) -qt_generate_deploy_qml_app_script( - TARGET nearby_qml_tray_app - OUTPUT_SCRIPT nearby_qml_tray_app_deploy_script -) -install(SCRIPT "${nearby_qml_tray_app_deploy_script}") - qt_generate_deploy_qml_app_script( TARGET nearby_qml_file_tray_app OUTPUT_SCRIPT nearby_qml_file_tray_app_deploy_script diff --git a/sharing/linux/qml_tray_app/Main.qml b/sharing/linux/qml_tray_app/Main.qml deleted file mode 100644 index 059da41f..00000000 --- a/sharing/linux/qml_tray_app/Main.qml +++ /dev/null @@ -1,858 +0,0 @@ -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts - -ApplicationWindow { - id: root - width: 1200 - height: 820 - minimumWidth: 980 - minimumHeight: 700 - visible: true - title: "Nearby QML Tray" - - property string apiEndpointId: "" - property string apiPayloadText: "" - property string queryMediumResult: "-" - property string queryPeerResult: "-" - readonly property color appBg: "#f5f6f8" - readonly property color surface: "#ffffff" - readonly property color border: "#d7dbe0" - readonly property color textPrimary: "#1f2328" - readonly property color textMuted: "#59636e" - - palette.window: appBg - palette.base: surface - palette.button: "#f0f3f7" - palette.text: textPrimary - palette.windowText: textPrimary - palette.buttonText: textPrimary - palette.placeholderText: textMuted - palette.highlight: "#2f6feb" - palette.highlightedText: "#ffffff" - - background: Rectangle { - color: root.appBg - } - - ListModel { - id: connectedEndpointsModel - } - - ListModel { - id: payloadEventsModel - } - - function endpointLabel(endpointId) { - var label = nearbyController.peerNameForEndpoint(endpointId) - if (!label || label.length === 0 || label === "Unknown device") { - return "Unknown device" - } - return label - } - - function formatBytes(bytes) { - if (bytes === undefined || bytes === null) { - return "0 B" - } - var value = Number(bytes) - if (!isFinite(value) || value < 0) { - return "0 B" - } - var units = ["B", "KB", "MB", "GB", "TB"] - var unit = 0 - while (value >= 1024 && unit < units.length - 1) { - value /= 1024 - unit += 1 - } - return (value >= 10 || unit === 0 ? value.toFixed(0) : value.toFixed(1)) + " " + units[unit] - } - - function refreshConnectedEndpointsModel() { - var selectedId = targetCombo.currentValue ? String(targetCombo.currentValue) : "" - connectedEndpointsModel.clear() - var devices = nearbyController.connectedDevices - for (var i = 0; i < devices.length; ++i) { - var endpointId = String(devices[i]) - connectedEndpointsModel.append({ - "endpointId": endpointId, - "label": endpointLabel(endpointId) - }) - } - var nextIndex = -1 - for (var j = 0; j < connectedEndpointsModel.count; ++j) { - if (connectedEndpointsModel.get(j).endpointId === selectedId) { - nextIndex = j - break - } - } - if (nextIndex < 0 && connectedEndpointsModel.count > 0) { - nextIndex = 0 - } - targetCombo.currentIndex = nextIndex - } - - onClosing: function(close) { - close.accepted = false - root.hide() - nearbyController.hideToTray() - } - - header: ToolBar { - height: 54 - - // background: Rectangle { - // color: root.surface - // border.color: root.border - // } - - RowLayout { - anchors.fill: parent - anchors.leftMargin: 12 - anchors.rightMargin: 12 - spacing: 10 - - Label { - text: "Nearby Control" - font.bold: true - font.pixelSize: 18 - color: root.textPrimary - } - - Item { Layout.fillWidth: true } - - Label { - text: nearbyController.running ? "Running" : "Stopped" - color: nearbyController.running ? "#1f7a1f" : "#a33" - font.bold: true - } - - Button { - text: nearbyController.running ? "Stop" : "Start" - onClicked: { - if (nearbyController.running) { - nearbyController.stop() - } else { - nearbyController.start() - } - } - } - - Button { - text: "Hide To Tray" - onClicked: { - root.hide() - nearbyController.hideToTray() - } - } - } - } - - ColumnLayout { - anchors.fill: parent - anchors.margins: 12 - spacing: 10 - - Frame { - Layout.fillWidth: true - padding: 10 - background: Rectangle { - color: root.surface - border.color: root.border - radius: 6 - } - - ColumnLayout { - anchors.fill: parent - spacing: 8 - - Label { - text: "Settings" - font.bold: true - } - - GridLayout { - Layout.fillWidth: true - columns: 8 - columnSpacing: 8 - rowSpacing: 8 - - Label { text: "Mode" } - ComboBox { - id: modeCombo - model: ["Receive", "Send"] - currentIndex: nearbyController.mode === "Send" ? 1 : 0 - onActivated: nearbyController.mode = currentText - } - - Label { text: "Incoming" } - CheckBox { - id: autoAcceptIncomingCheckbox - text: "Auto accept" - checked: nearbyController.autoAcceptIncoming - onCheckedChanged: nearbyController.autoAcceptIncoming = checked - } - - ColumnLayout { - anchors.leftMargin: 30 - anchors.rightMargin: 30 - Label { - anchors.fill : parent - text: "Mediums" - Layout.alignment: Qt.AlignTop - horizontalAlignment: Text.AlignHCenter - topPadding: 6 - } - RowLayout { - spacing: 4 - CheckBox { - id: bluetoothCheckbox - text: "Bluetooth" - checked: nearbyController.bluetoothEnabled - onCheckedChanged: nearbyController.bluetoothEnabled = checked - } - CheckBox { - id: bleCheckbox - text: "BLE" - checked: nearbyController.bleEnabled - onCheckedChanged: nearbyController.bleEnabled = checked - } - CheckBox { - id: wifiLanCheckbox - text: "WiFi LAN" - checked: nearbyController.wifiLanEnabled - onCheckedChanged: nearbyController.wifiLanEnabled = checked - } - CheckBox { - id: wifiHotspotCheckbox - text: "WiFi Hotspot" - checked: nearbyController.wifiHotspotEnabled - onCheckedChanged: nearbyController.wifiHotspotEnabled = checked - } - CheckBox { - id: webRtcCheckbox - text: "WebRTC" - checked: nearbyController.webRtcEnabled - onCheckedChanged: nearbyController.webRtcEnabled = checked - } - } - } - - Label { text: "Strategy" } - ComboBox { - id: strategyCombo - Layout.preferredWidth: 170 - model: ["P2pCluster", "P2pStar", "P2pPointToPoint"] - currentIndex: { - var strategy = String(nearbyController.connectionStrategy) - if (strategy === "P2pStar") - return 1 - if (strategy === "P2pPointToPoint") - return 2 - return 0 - } - onActivated: nearbyController.connectionStrategy = currentText - } - - Label { text: "Device" } - TextField { - Layout.preferredWidth: 180 - text: nearbyController.deviceName - onEditingFinished: nearbyController.deviceName = text - } - - Label { text: "Service ID" } - TextField { - Layout.fillWidth: true - Layout.columnSpan: 3 - text: nearbyController.serviceId - onEditingFinished: nearbyController.serviceId = text - } - - Label { text: "Log Path" } - TextField { - Layout.fillWidth: true - Layout.columnSpan: 7 - text: nearbyController.logPath - onEditingFinished: nearbyController.logPath = text - } - } - - Label { - Layout.fillWidth: true - text: "Status: " + nearbyController.statusMessage - elide: Text.ElideRight - } - } - } - - RowLayout { - Layout.fillWidth: true - Layout.fillHeight: true - spacing: 10 - - Frame { - Layout.fillHeight: true - Layout.preferredWidth: 420 - padding: 10 - background: Rectangle { - color: root.surface - border.color: root.border - radius: 6 - } - - ColumnLayout { - anchors.fill: parent - spacing: 10 - - Label { - text: "API Controls" - font.bold: true - } - - Frame { - Layout.fillWidth: true - Layout.preferredHeight: 150 - padding: 6 - background: Rectangle { - color: root.surface - border.color: root.border - radius: 4 - } - - ColumnLayout { - anchors.fill: parent - spacing: 4 - - Label { - text: "Incoming Requests" - font.bold: true - } - - ListView { - id: incomingRequestsList - Layout.fillWidth: true - Layout.fillHeight: true - clip: true - spacing: 4 - model: nearbyController.pendingConnections - - delegate: Rectangle { - required property string modelData - width: incomingRequestsList.width - height: 38 - color: root.surface - border.color: root.border - radius: 4 - - RowLayout { - anchors.fill: parent - anchors.leftMargin: 6 - anchors.rightMargin: 6 - spacing: 6 - - Label { - Layout.fillWidth: true - text: root.endpointLabel(modelData) - elide: Text.ElideRight - } - - Button { - text: "Accept" - onClicked: nearbyController.acceptIncoming(modelData) - } - - Button { - text: "Reject" - onClicked: nearbyController.rejectIncoming(modelData) - } - } - } - } - } - } - - TextField { - id: endpointField - Layout.fillWidth: true - Layout.minimumWidth: 0 - placeholderText: "Endpoint ID (advanced)" - text: root.apiEndpointId - onTextChanged: root.apiEndpointId = text - } - - GridLayout { - Layout.fillWidth: true - columns: 2 - columnSpacing: 6 - rowSpacing: 6 - - Button { - text: "Connect" - Layout.fillWidth: true - enabled: endpointField.text.trim().length > 0 - onClicked: nearbyController.connectToDevice(endpointField.text.trim()) - } - Button { - text: "Disconnect" - Layout.fillWidth: true - enabled: endpointField.text.trim().length > 0 - onClicked: nearbyController.disconnectDevice(endpointField.text.trim()) - } - Button { - text: "Accept" - Layout.fillWidth: true - enabled: endpointField.text.trim().length > 0 - onClicked: nearbyController.acceptIncoming(endpointField.text.trim()) - } - Button { - text: "Reject" - Layout.fillWidth: true - enabled: endpointField.text.trim().length > 0 - onClicked: nearbyController.rejectIncoming(endpointField.text.trim()) - } - } - - RowLayout { - Layout.fillWidth: true - spacing: 6 - - ComboBox { - id: targetCombo - Layout.fillWidth: true - Layout.minimumWidth: 0 - model: connectedEndpointsModel - textRole: "label" - valueRole: "endpointId" - displayText: currentIndex >= 0 ? currentText : "Select connected device" - } - - Button { - text: "Use ID" - enabled: targetCombo.currentValue !== undefined && targetCombo.currentValue !== null - onClicked: { - endpointField.text = String(targetCombo.currentValue) - root.apiEndpointId = endpointField.text - } - } - } - - TextField { - id: payloadField - Layout.fillWidth: true - Layout.minimumWidth: 0 - placeholderText: "Text payload" - text: root.apiPayloadText - onTextChanged: root.apiPayloadText = text - } - - GridLayout { - Layout.fillWidth: true - columns: 2 - columnSpacing: 6 - rowSpacing: 6 - - Button { - text: "Send Text" - Layout.fillWidth: true - enabled: endpointField.text.trim().length > 0 && payloadField.text.length > 0 - onClicked: nearbyController.sendText(endpointField.text.trim(), payloadField.text) - } - - Button { - text: "Get Medium" - Layout.fillWidth: true - enabled: endpointField.text.trim().length > 0 - onClicked: root.queryMediumResult = nearbyController.mediumForEndpoint(endpointField.text.trim()) - } - - Button { - text: "Upgrade Bandwidth" - Layout.fillWidth: true - enabled: endpointField.text.trim().length > 0 - onClicked: nearbyController.initiateBandwidthUpgrade(endpointField.text.trim()) - } - - Button { - text: "Get Peer Name" - Layout.fillWidth: true - enabled: endpointField.text.trim().length > 0 - onClicked: root.queryPeerResult = nearbyController.peerNameForEndpoint(endpointField.text.trim()) - } - } - - GridLayout { - Layout.fillWidth: true - columns: 2 - columnSpacing: 8 - - Label { text: "Medium" } - Label { - text: root.queryMediumResult - Layout.fillWidth: true - elide: Text.ElideRight - } - - Label { text: "Peer" } - Label { - text: root.queryPeerResult - Layout.fillWidth: true - elide: Text.ElideRight - } - } - - GridLayout { - Layout.fillWidth: true - columns: 2 - columnSpacing: 6 - - Button { - text: "Clear Transfers" - Layout.fillWidth: true - onClicked: nearbyController.clearTransfers() - } - - Button { - text: "Hide To Tray" - Layout.fillWidth: true - onClicked: { - root.hide() - nearbyController.hideToTray() - } - } - } - - Label { - text: "Payload Events" - font.bold: true - } - - ListView { - Layout.fillWidth: true - Layout.fillHeight: true - clip: true - model: payloadEventsModel - spacing: 4 - - delegate: Rectangle { - required property var model - width: ListView.view.width - height: 44 - color: root.surface - border.color: root.border - radius: 4 - - ColumnLayout { - anchors.fill: parent - anchors.leftMargin: 6 - anchors.rightMargin: 6 - spacing: 0 - - Label { - Layout.fillWidth: true - text: model.peer - font.bold: true - elide: Text.ElideRight - } - Label { - Layout.fillWidth: true - text: model.type + ": " + model.value - elide: Text.ElideRight - } - } - } - } - } - } - - ColumnLayout { - Layout.fillWidth: true - Layout.fillHeight: true - spacing: 10 - - Frame { - Layout.fillWidth: true - Layout.preferredHeight: 320 - padding: 8 - background: Rectangle { - color: root.surface - border.color: root.border - radius: 6 - } - - ColumnLayout { - anchors.fill: parent - spacing: 6 - - Label { - text: "Endpoints" - font.bold: true - } - - TabBar { - id: endpointTabs - Layout.fillWidth: true - - TabButton { text: "Discovered" } - TabButton { text: "Pending" } - TabButton { text: "Connected" } - } - - StackLayout { - Layout.fillWidth: true - Layout.fillHeight: true - currentIndex: endpointTabs.currentIndex - - ListView { - id: discoveredList - clip: true - spacing: 4 - model: nearbyController.discoveredDevices - - delegate: Rectangle { - required property string modelData - width: discoveredList.width - height: 42 - color: root.surface - border.color: root.border - radius: 4 - - RowLayout { - anchors.fill: parent - anchors.leftMargin: 8 - anchors.rightMargin: 8 - - Label { - Layout.fillWidth: true - text: root.endpointLabel(modelData) - elide: Text.ElideRight - } - - Button { - text: "Use" - onClicked: { - endpointField.text = modelData - root.apiEndpointId = modelData - } - } - - Button { - text: "Connect" - onClicked: nearbyController.connectToDevice(modelData) - } - } - } - } - - ListView { - id: pendingList - clip: true - spacing: 4 - model: nearbyController.pendingConnections - - delegate: Rectangle { - required property string modelData - width: pendingList.width - height: 42 - color: root.surface - border.color: root.border - radius: 4 - - RowLayout { - anchors.fill: parent - anchors.leftMargin: 8 - anchors.rightMargin: 8 - - Label { - Layout.fillWidth: true - text: root.endpointLabel(modelData) - elide: Text.ElideRight - } - - Button { - text: "Use" - onClicked: { - endpointField.text = modelData - root.apiEndpointId = modelData - } - } - - Button { - text: "Accept" - onClicked: nearbyController.acceptIncoming(modelData) - } - - Button { - text: "Reject" - onClicked: nearbyController.rejectIncoming(modelData) - } - } - } - } - - ListView { - id: connectedList - clip: true - spacing: 4 - model: nearbyController.connectedDevices - - delegate: Rectangle { - required property string modelData - width: connectedList.width - height: 46 - color: root.surface - border.color: root.border - radius: 4 - - RowLayout { - anchors.fill: parent - anchors.leftMargin: 8 - anchors.rightMargin: 8 - - Label { - Layout.fillWidth: true - text: root.endpointLabel(modelData) - elide: Text.ElideRight - } - - Label { - text: nearbyController.mediumForEndpoint(modelData) - } - - Button { - text: "Use" - onClicked: { - endpointField.text = modelData - root.apiEndpointId = modelData - } - } - - Button { - text: "Disconnect" - onClicked: nearbyController.disconnectDevice(modelData) - } - } - } - } - } - } - } - - Frame { - Layout.fillWidth: true - Layout.fillHeight: true - padding: 8 - background: Rectangle { - color: root.surface - border.color: root.border - radius: 6 - } - - ColumnLayout { - anchors.fill: parent - spacing: 6 - - RowLayout { - Layout.fillWidth: true - - Label { - text: "Transfers" - font.bold: true - } - - Item { Layout.fillWidth: true } - - Button { - text: "Clear" - onClicked: nearbyController.clearTransfers() - } - } - - ListView { - id: transferList - Layout.fillWidth: true - Layout.fillHeight: true - clip: true - spacing: 6 - model: nearbyController.transfers - - delegate: Rectangle { - required property var modelData - width: transferList.width - height: 86 - color: root.surface - border.color: root.border - radius: 4 - - ColumnLayout { - anchors.fill: parent - anchors.leftMargin: 8 - anchors.rightMargin: 8 - spacing: 4 - - RowLayout { - Layout.fillWidth: true - - Label { - Layout.fillWidth: true - text: modelData.direction + " | " + root.endpointLabel(modelData.endpointId) + " | payload " + modelData.payloadId - elide: Text.ElideRight - } - - Label { text: modelData.status } - Label { text: modelData.medium } - } - - ProgressBar { - Layout.fillWidth: true - from: 0 - to: 1 - value: modelData.progress - } - - Label { - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - text: root.formatBytes(modelData.bytesTransferred) + " / " + root.formatBytes(modelData.totalBytes) - color: root.textMuted - } - } - } - } - } - } - } - } - } - - Connections { - target: nearbyController - - function onConnectedDevicesChanged() { - root.refreshConnectedEndpointsModel() - } - - function onPendingConnectionsChanged() { - if (nearbyController.pendingConnections.length > 0) { - endpointTabs.currentIndex = 1 - } - } - - function onPayloadReceived(endpoint_id, type, value) { - payloadEventsModel.insert(0, { - "peer": root.endpointLabel(endpoint_id), - "type": type, - "value": String(value) - }) - if (payloadEventsModel.count > 200) { - payloadEventsModel.remove(payloadEventsModel.count - 1) - } - } - - function onModeChanged() { - modeCombo.currentIndex = nearbyController.mode === "Send" ? 1 : 0 - } - } - - Component.onCompleted: refreshConnectedEndpointsModel() -} diff --git a/sharing/linux/qml_tray_app/README.md b/sharing/linux/qml_tray_app/README.md index 26275c3d..a639e534 100644 --- a/sharing/linux/qml_tray_app/README.md +++ b/sharing/linux/qml_tray_app/README.md @@ -1,6 +1,6 @@ -# Nearby QML Tray App +# Nearby File Share Tray App -This folder contains a Qt/QML tray application backend and UI wired to: +This folder contains the Qt/QML **FileShareTray** application — a system tray app for file sharing via Nearby Connections, wired to: - `nearby::sharing::linux::NearbyConnectionsServiceLinux` - Send mode (discovery + connect) @@ -12,10 +12,11 @@ This folder contains a Qt/QML tray application backend and UI wired to: ## Files -- `main.cpp`: Qt app bootstrap + system tray behavior. -- `nearby_tray_controller.h/.cc`: QML-facing backend wrapper around Nearby Connections. -- `Main.qml`: UI for send/receive workflows and transfer monitoring. -- `resources.qrc`: embeds `Main.qml`. +- `file_share_tray_main.cpp`: Qt app bootstrap + system tray behavior. +- `file_share_tray_controller.h/.cc`: QML-facing backend wrapper around Nearby Connections. +- `FileShareTray.qml`: Top-level UI for the file share tray app. +- `components/`: Shared QML UI components used by `FileShareTray.qml`. +- `resources_file_share.qrc`: Embeds `FileShareTray.qml` and components. ## Runtime behavior @@ -64,7 +65,7 @@ cmake --install build Bundle output: -- `dist/bin/nearby_qml_tray_app` +- `dist/bin/nearby_qml_file_tray_app` - `dist/bin/libnearby_connections_service_linux_shared.so` The app is installed with `INSTALL_RPATH=$ORIGIN`, so it resolves the Nearby @@ -86,6 +87,6 @@ Output: This zip is created from the CMake install tree and includes: -- `nearby_qml_tray_app` +- `nearby_qml_file_tray_app` - `libnearby_connections_service_linux_shared.so` - Qt runtime libs/plugins/QML imports discovered by Qt deploy tooling diff --git a/sharing/linux/qml_tray_app/main.cpp b/sharing/linux/qml_tray_app/main.cpp deleted file mode 100644 index a07319aa..00000000 --- a/sharing/linux/qml_tray_app/main.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "nearby_tray_controller.h" - -namespace { - -QIcon BuildTintedSymbolicIcon(const QString& source, const QColor& color) { - QIcon source_icon(source); - if (source_icon.isNull()) { - return QIcon(); - } - - QIcon tinted_icon; - for (int size : {16, 18, 20, 22, 24, 32}) { - QPixmap pixmap = source_icon.pixmap(size, size); - if (pixmap.isNull()) { - continue; - } - - QPixmap tinted(pixmap.size()); - tinted.fill(Qt::transparent); - - QPainter painter(&tinted); - painter.drawPixmap(0, 0, pixmap); - painter.setCompositionMode(QPainter::CompositionMode_SourceIn); - painter.fillRect(tinted.rect(), color); - painter.end(); - - tinted_icon.addPixmap(tinted); - } - - return tinted_icon; -} - -} // namespace - -int main(int argc, char* argv[]) { - QApplication app(argc, argv); - app.setQuitOnLastWindowClosed(false); - - NearbyTrayController controller; - - QQmlApplicationEngine engine; - engine.rootContext()->setContextProperty("nearbyController", &controller); - engine.load(QUrl(QStringLiteral("qrc:/qml/Main.qml"))); - if (engine.rootObjects().isEmpty()) { - return 1; - } - - auto* window = qobject_cast(engine.rootObjects().first()); - if (window == nullptr) { - return 1; - } - - const auto resolve_tray_icon = [&app]() { - // Render the bundled symbolic icon with palette text color so it adapts to light/dark themes. - const QColor symbolic_color = app.palette().color(QPalette::WindowText); - QIcon tray_icon = BuildTintedSymbolicIcon( - QStringLiteral(":/icons/tray_icon-symbolic.svg"), symbolic_color); - - // Fallback to system themed icon. - if (tray_icon.isNull()) { - tray_icon = QIcon::fromTheme(QStringLiteral("network-wireless-symbolic")); - } - - // Fallback to custom PNG icon. - if (tray_icon.isNull()) { - tray_icon = QIcon(QStringLiteral(":/icons/tray_icon.png")); - } - - // Final fallback. - if (tray_icon.isNull()) { - tray_icon = app.windowIcon(); - } - return tray_icon; - }; - - QIcon tray_icon = resolve_tray_icon(); - QSystemTrayIcon tray(tray_icon); - tray.setToolTip(QStringLiteral("Nearby QML Tray")); - - QMenu tray_menu; - QAction* show_action = tray_menu.addAction(QStringLiteral("Show")); - QAction* hide_action = tray_menu.addAction(QStringLiteral("Hide")); - tray_menu.addSeparator(); - QAction* quit_action = tray_menu.addAction(QStringLiteral("Quit")); - - QObject::connect(show_action, &QAction::triggered, window, [window]() { - window->show(); - window->raise(); - window->requestActivate(); - }); - QObject::connect(hide_action, &QAction::triggered, window, [window]() { - window->hide(); - }); - QObject::connect(quit_action, &QAction::triggered, &app, [&controller, &app]() { - controller.stop(); - app.quit(); - }); - - QObject::connect(&tray, &QSystemTrayIcon::activated, window, - [&tray, window](QSystemTrayIcon::ActivationReason reason) { - if (reason != QSystemTrayIcon::Trigger && - reason != QSystemTrayIcon::DoubleClick) { - return; - } - if (window->isVisible()) { - window->hide(); - } else { - window->show(); - window->raise(); - window->requestActivate(); - } - }); - - QObject::connect(&controller, &NearbyTrayController::requestTrayMessage, &tray, - [&tray](const QString& title, const QString& body) { - tray.showMessage(title, body, QSystemTrayIcon::Information, - 3000); - }); - - QObject::connect(&app, &QCoreApplication::aboutToQuit, &controller, - [&controller]() { controller.stop(); }); - QObject::connect(app.styleHints(), &QStyleHints::colorSchemeChanged, &tray, - [&tray, &resolve_tray_icon](Qt::ColorScheme) { - tray.setIcon(resolve_tray_icon()); - }); - - tray.setContextMenu(&tray_menu); - tray.show(); - - return app.exec(); -} diff --git a/sharing/linux/qml_tray_app/nearby_tray_controller.cc b/sharing/linux/qml_tray_app/nearby_tray_controller.cc deleted file mode 100644 index 18c0fef0..00000000 --- a/sharing/linux/qml_tray_app/nearby_tray_controller.cc +++ /dev/null @@ -1,1213 +0,0 @@ -#include "nearby_tray_controller.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace { - -using NearbyConnectionsQtFacade = - nearby::sharing::NearbyConnectionsQtFacade; - -QString NormalizeMediumsMode(QString mode) { - mode = mode.trimmed().toLower(); - if (mode == QStringLiteral("all") || mode == QStringLiteral("bluetooth") || - mode == QStringLiteral("ble") || mode == QStringLiteral("wifi_lan") || - mode == QStringLiteral("wifi_hotspot") || - mode == QStringLiteral("web_rtc") || - mode == QStringLiteral("balanced")) { - return mode; - } - return QStringLiteral("balanced"); -} - -NearbyConnectionsQtFacade::MediumSelection BuildMediumSelectionForMode( - const QString& normalized_mode) { - NearbyConnectionsQtFacade::MediumSelection selection; - selection.bluetooth = false; - selection.ble = false; - selection.web_rtc = false; - selection.wifi_lan = false; - selection.wifi_hotspot = false; - - if (normalized_mode == QStringLiteral("all")) { - selection.bluetooth = true; - selection.ble = true; - selection.web_rtc = true; - selection.wifi_lan = true; - selection.wifi_hotspot = true; - } else if (normalized_mode == QStringLiteral("bluetooth")) { - selection.bluetooth = true; - } else if (normalized_mode == QStringLiteral("ble")) { - selection.ble = true; - } else if (normalized_mode == QStringLiteral("wifi_lan")) { - selection.wifi_lan = true; - } else if (normalized_mode == QStringLiteral("wifi_hotspot")) { - selection.wifi_hotspot = true; - } else if (normalized_mode == QStringLiteral("web_rtc")) { - selection.web_rtc = true; - } else { - // Balanced default mirrors previous behavior. - selection.bluetooth = true; - selection.ble = true; - selection.wifi_lan = true; - } - return selection; -} - -QString NormalizeConnectionStrategy(QString strategy) { - const QString token = strategy.trimmed().toLower(); - if (token == QStringLiteral("p2pstar") || token == QStringLiteral("star")) { - return QStringLiteral("P2pStar"); - } - if (token == QStringLiteral("p2ppointtopoint") || - token == QStringLiteral("pointtopoint") || - token == QStringLiteral("point_to_point")) { - return QStringLiteral("P2pPointToPoint"); - } - return QStringLiteral("P2pCluster"); -} - -NearbyConnectionsQtFacade::Strategy StrategyFromName( - const QString& normalized_strategy) { - if (normalized_strategy == QStringLiteral("P2pStar")) { - return NearbyConnectionsQtFacade::Strategy::kP2pStar; - } - if (normalized_strategy == QStringLiteral("P2pPointToPoint")) { - return NearbyConnectionsQtFacade::Strategy::kP2pPointToPoint; - } - return NearbyConnectionsQtFacade::Strategy::kP2pCluster; -} - -} // namespace - -NearbyTrayController::NearbyTrayController(QObject* parent) : QObject(parent) { - const QString host = QSysInfo::machineHostName(); - if (!host.isEmpty()) { - device_name_ = host; - } - LoadSettings(); - ReopenLogFile(); - LogLine(QStringLiteral("Started Nearby tray controller")); -} - -NearbyTrayController::~NearbyTrayController() { - stop(); - if (log_file_.isOpen()) { - log_file_.close(); - } -} - -void NearbyTrayController::LoadSettings() { - QSettings settings(QStringLiteral("Nearby"), QStringLiteral("QmlTrayApp")); - - const QString stored_mode = - settings.value(QStringLiteral("mode"), mode_).toString(); - mode_ = stored_mode.trimmed().toLower() == QStringLiteral("send") - ? QStringLiteral("Send") - : QStringLiteral("Receive"); - - const QString stored_device_name = - settings.value(QStringLiteral("deviceName"), device_name_) - .toString() - .trimmed(); - if (!stored_device_name.isEmpty()) { - device_name_ = stored_device_name; - } - - const QString stored_service_id = - settings - .value(QStringLiteral("serviceId"), - QString::fromStdString(service_id_)) - .toString() - .trimmed(); - if (!stored_service_id.isEmpty()) { - service_id_ = stored_service_id.toStdString(); - } - - mediums_mode_ = NormalizeMediumsMode( - settings.value(QStringLiteral("mediumsMode"), mediums_mode_).toString()); - bluetooth_enabled_ = settings - .value(QStringLiteral("bluetoothEnabled"), - bluetooth_enabled_) - .toBool(); - ble_enabled_ = settings.value(QStringLiteral("bleEnabled"), ble_enabled_).toBool(); - wifi_lan_enabled_ = settings - .value(QStringLiteral("wifiLanEnabled"), - wifi_lan_enabled_) - .toBool(); - wifi_hotspot_enabled_ = settings - .value(QStringLiteral("wifiHotspotEnabled"), - wifi_hotspot_enabled_) - .toBool(); - web_rtc_enabled_ = - settings.value(QStringLiteral("webRtcEnabled"), web_rtc_enabled_).toBool(); - auto_accept_incoming_ = settings - .value(QStringLiteral("autoAcceptIncoming"), - auto_accept_incoming_) - .toBool(); - connection_strategy_ = NormalizeConnectionStrategy( - settings - .value(QStringLiteral("connectionStrategy"), connection_strategy_) - .toString()); - - const QString stored_log_path = - settings.value(QStringLiteral("logPath"), log_path_).toString().trimmed(); - if (!stored_log_path.isEmpty()) { - log_path_ = stored_log_path; - } -} - -void NearbyTrayController::SaveSettings() const { - QSettings settings(QStringLiteral("Nearby"), QStringLiteral("QmlTrayApp")); - settings.setValue(QStringLiteral("mode"), mode_); - settings.setValue(QStringLiteral("deviceName"), device_name_); - settings.setValue(QStringLiteral("serviceId"), - QString::fromStdString(service_id_)); - settings.setValue(QStringLiteral("mediumsMode"), mediums_mode_); - settings.setValue(QStringLiteral("bluetoothEnabled"), bluetooth_enabled_); - settings.setValue(QStringLiteral("bleEnabled"), ble_enabled_); - settings.setValue(QStringLiteral("wifiLanEnabled"), wifi_lan_enabled_); - settings.setValue(QStringLiteral("wifiHotspotEnabled"), wifi_hotspot_enabled_); - settings.setValue(QStringLiteral("webRtcEnabled"), web_rtc_enabled_); - settings.setValue(QStringLiteral("autoAcceptIncoming"), auto_accept_incoming_); - settings.setValue(QStringLiteral("connectionStrategy"), connection_strategy_); - settings.setValue(QStringLiteral("logPath"), log_path_); - settings.sync(); -} - -void NearbyTrayController::setMode(const QString& mode) { - const QString normalized = - mode.trimmed().toLower() == QStringLiteral("send") - ? QStringLiteral("Send") - : QStringLiteral("Receive"); - if (mode_ == normalized) { - return; - } - mode_ = normalized; - emit modeChanged(); - SaveSettings(); - LogLine(QStringLiteral("Mode changed to %1").arg(mode_)); - if (running_) { - stop(); - start(); - } -} - -void NearbyTrayController::setDeviceName(const QString& device_name) { - const QString trimmed = device_name.trimmed(); - if (trimmed.isEmpty() || trimmed == device_name_) { - return; - } - device_name_ = trimmed; - emit deviceNameChanged(); - SaveSettings(); - LogLine(QStringLiteral("Device name changed to %1").arg(device_name_)); -} - -void NearbyTrayController::setServiceId(const QString& service_id) { - const std::string value = service_id.trimmed().toStdString(); - if (value.empty() || value == service_id_) { - return; - } - service_id_ = value; - emit serviceIdChanged(); - SaveSettings(); - LogLine(QStringLiteral("Service ID changed to %1") - .arg(QString::fromStdString(service_id_))); -} - -void NearbyTrayController::setMediumsMode(const QString& mode) { - const QString normalized = NormalizeMediumsMode(mode); - if (mediums_mode_ == normalized) { - return; - } - mediums_mode_ = normalized; - emit mediumsModeChanged(); - SaveSettings(); - LogLine(QStringLiteral("Mediums mode changed to %1").arg(mediums_mode_)); - if (running_) { - stop(); - start(); - } -} - -void NearbyTrayController::setBluetoothEnabled(bool enabled) { - if (bluetooth_enabled_ == enabled) { - return; - } - bluetooth_enabled_ = enabled; - emit bluetoothEnabledChanged(); - SaveSettings(); - LogLine(QStringLiteral("Bluetooth %1").arg(enabled ? "enabled" : "disabled")); - if (running_) { - stop(); - start(); - } -} - -void NearbyTrayController::setBleEnabled(bool enabled) { - if (ble_enabled_ == enabled) { - return; - } - ble_enabled_ = enabled; - emit bleEnabledChanged(); - SaveSettings(); - LogLine(QStringLiteral("BLE %1").arg(enabled ? "enabled" : "disabled")); - if (running_) { - stop(); - start(); - } -} - -void NearbyTrayController::setWifiLanEnabled(bool enabled) { - if (wifi_lan_enabled_ == enabled) { - return; - } - wifi_lan_enabled_ = enabled; - emit wifiLanEnabledChanged(); - SaveSettings(); - LogLine(QStringLiteral("WiFi LAN %1").arg(enabled ? "enabled" : "disabled")); - if (running_) { - stop(); - start(); - } -} - -void NearbyTrayController::setWifiHotspotEnabled(bool enabled) { - if (wifi_hotspot_enabled_ == enabled) { - return; - } - wifi_hotspot_enabled_ = enabled; - emit wifiHotspotEnabledChanged(); - SaveSettings(); - LogLine(QStringLiteral("WiFi Hotspot %1").arg(enabled ? "enabled" : "disabled")); - if (running_) { - stop(); - start(); - } -} - -void NearbyTrayController::setWebRtcEnabled(bool enabled) { - if (web_rtc_enabled_ == enabled) { - return; - } - web_rtc_enabled_ = enabled; - emit webRtcEnabledChanged(); - SaveSettings(); - LogLine(QStringLiteral("WebRTC %1").arg(enabled ? "enabled" : "disabled")); - if (running_) { - stop(); - start(); - } -} - -void NearbyTrayController::setAutoAcceptIncoming(bool enabled) { - if (auto_accept_incoming_ == enabled) { - return; - } - auto_accept_incoming_ = enabled; - emit autoAcceptIncomingChanged(); - SaveSettings(); - LogLine(QStringLiteral("Auto-accept incoming connections %1") - .arg(enabled ? "enabled" : "disabled")); -} - -void NearbyTrayController::setConnectionStrategy(const QString& strategy) { - const QString normalized = NormalizeConnectionStrategy(strategy); - if (connection_strategy_ == normalized) { - return; - } - connection_strategy_ = normalized; - emit connectionStrategyChanged(); - SaveSettings(); - LogLine(QStringLiteral("Connection strategy changed to %1") - .arg(connection_strategy_)); - if (running_) { - stop(); - start(); - } -} - -void NearbyTrayController::setLogPath(const QString& path) { - const QString trimmed = path.trimmed(); - if (trimmed.isEmpty() || trimmed == log_path_) { - return; - } - log_path_ = trimmed; - emit logPathChanged(); - SaveSettings(); - ReopenLogFile(); - LogLine(QStringLiteral("Log path changed to %1").arg(log_path_)); -} - -void NearbyTrayController::start() { - if (running_) { - return; - } - running_ = true; - emit runningChanged(); - - if (mode_ == QStringLiteral("Send")) { - startSendMode(); - } else { - startReceiveMode(); - } -} - -void NearbyTrayController::stop() { - if (!running_) { - return; - } - running_ = false; - emit runningChanged(); - - service_.StopDiscovery( - service_id_, [this](NearbyConnectionsQtFacade::Status status) { - QMetaObject::invokeMethod( - this, - [this, status]() { - LogLine(QStringLiteral("StopDiscovery: %1") - .arg(StatusToString(status))); - }, - Qt::QueuedConnection); - }); - service_.StopAdvertising( - service_id_, [this](NearbyConnectionsQtFacade::Status status) { - QMetaObject::invokeMethod( - this, - [this, status]() { - LogLine(QStringLiteral("StopAdvertising: %1") - .arg(StatusToString(status))); - }, - Qt::QueuedConnection); - }); - service_.StopAllEndpoints( - [this](NearbyConnectionsQtFacade::Status status) { - QMetaObject::invokeMethod( - this, - [this, status]() { - LogLine(QStringLiteral("StopAllEndpoints: %1") - .arg(StatusToString(status))); - }, - Qt::QueuedConnection); - }); - - discovered_devices_.clear(); - connected_devices_.clear(); - pending_connections_.clear(); - endpoint_peer_names_.clear(); - endpoint_mediums_.clear(); - emit discoveredDevicesChanged(); - emit connectedDevicesChanged(); - emit pendingConnectionsChanged(); - emit endpointMediumsChanged(); - - SetStatus(QStringLiteral("Stopped")); -} - -void NearbyTrayController::connectToDevice(const QString& endpoint_id) { - const QString endpoint = endpoint_id.trimmed(); - if (endpoint.isEmpty()) { - return; - } - const QString peer = PeerLabelForEndpoint(endpoint); - if (!running_) { - start(); - } - - SetStatus(QStringLiteral("Requesting connection to %1").arg(peer)); - LogLine(QStringLiteral("RequestConnection %1").arg(endpoint)); - - service_.RequestConnection( - service_id_, BuildEndpointInfo(), endpoint.toStdString(), - BuildConnectionOptions(), BuildConnectionListener(), - [this, endpoint](NearbyConnectionsQtFacade::Status status) { - QMetaObject::invokeMethod( - this, - [this, endpoint, status]() { - const QString peer = PeerLabelForEndpoint(endpoint); - SetStatus(QStringLiteral("RequestConnection(%1): %2") - .arg(peer, StatusToString(status))); - LogLine(QStringLiteral("RequestConnection(%1): %2") - .arg(endpoint, StatusToString(status))); - }, - Qt::QueuedConnection); - }); -} - -void NearbyTrayController::disconnectDevice(const QString& endpoint_id) { - const QString endpoint = endpoint_id.trimmed(); - if (endpoint.isEmpty()) { - return; - } - service_.DisconnectFromEndpoint( - service_id_, endpoint.toStdString(), - [this, endpoint](NearbyConnectionsQtFacade::Status status) { - QMetaObject::invokeMethod( - this, - [this, endpoint, status]() { - const QString peer = PeerLabelForEndpoint(endpoint); - SetStatus(QStringLiteral("Disconnect(%1): %2") - .arg(peer, StatusToString(status))); - LogLine(QStringLiteral("Disconnect(%1): %2") - .arg(endpoint, StatusToString(status))); - if (status == NearbyConnectionsQtFacade::Status::kSuccess) { - RemoveConnectedDevice(endpoint); - RemovePendingConnection(endpoint); - endpoint_peer_names_.remove(endpoint); - endpoint_mediums_.remove(endpoint); - emit endpointMediumsChanged(); - } - }, - Qt::QueuedConnection); - }); -} - -void NearbyTrayController::acceptIncoming(const QString& endpoint_id) { - const QString endpoint = endpoint_id.trimmed(); - if (endpoint.isEmpty()) { - return; - } - RemovePendingConnection(endpoint); - - service_.AcceptConnection( - service_id_, endpoint.toStdString(), BuildPayloadListener(), - [this, endpoint](NearbyConnectionsQtFacade::Status status) { - QMetaObject::invokeMethod( - this, - [this, endpoint, status]() { - const QString peer = PeerLabelForEndpoint(endpoint); - SetStatus(QStringLiteral("AcceptConnection(%1): %2") - .arg(peer, StatusToString(status))); - LogLine(QStringLiteral("AcceptConnection(%1): %2") - .arg(endpoint, StatusToString(status))); - }, - Qt::QueuedConnection); - }); -} - -void NearbyTrayController::rejectIncoming(const QString& endpoint_id) { - const QString endpoint = endpoint_id.trimmed(); - if (endpoint.isEmpty()) { - return; - } - RemovePendingConnection(endpoint); - disconnectDevice(endpoint); -} - -void NearbyTrayController::initiateBandwidthUpgrade(const QString& endpoint_id) { - const QString endpoint = endpoint_id.trimmed(); - if (endpoint.isEmpty()) { - return; - } - service_.InitiateBandwidthUpgrade( - service_id_, endpoint.toStdString(), - [this, endpoint](NearbyConnectionsQtFacade::Status status) { - QMetaObject::invokeMethod( - this, - [this, endpoint, status]() { - const QString peer = PeerLabelForEndpoint(endpoint); - SetStatus(QStringLiteral("InitiateBandwidthUpgrade(%1): %2") - .arg(peer, StatusToString(status))); - LogLine(QStringLiteral("InitiateBandwidthUpgrade(%1): %2") - .arg(endpoint, StatusToString(status))); - }, - Qt::QueuedConnection); - }); -} - -void NearbyTrayController::sendText(const QString& endpoint_id, - const QString& text) { - const QString endpoint = endpoint_id.trimmed(); - if (endpoint.isEmpty() || text.isEmpty()) { - return; - } - - QByteArray utf8 = text.toUtf8(); - std::vector bytes(utf8.begin(), utf8.end()); - auto payload = service_.CreateBytesPayload(std::move(bytes)); - const qlonglong payload_id = payload.id; - - UpsertTransfer(endpoint, payload_id, QStringLiteral("Queued"), 0, - static_cast(bytes.size()), - QStringLiteral("outgoing")); - - const std::vector endpoint_ids{endpoint.toStdString()}; - service_.SendPayload( - service_id_, endpoint_ids, std::move(payload), - [this, endpoint, payload_id](NearbyConnectionsQtFacade::Status status) { - QMetaObject::invokeMethod( - this, - [this, endpoint, payload_id, status]() { - LogLine(QStringLiteral("SendPayload(%1, %2): %3") - .arg(endpoint) - .arg(payload_id) - .arg(StatusToString(status))); - if (status != NearbyConnectionsQtFacade::Status::kSuccess) { - UpsertTransfer(endpoint, payload_id, QStringLiteral("SendFailed"), - 0, 0, QStringLiteral("outgoing")); - } - }, - Qt::QueuedConnection); - }); -} - -QString NearbyTrayController::mediumForEndpoint(const QString& endpoint_id) const { - return endpoint_mediums_.value(endpoint_id).toString(); -} - -QString NearbyTrayController::peerNameForEndpoint(const QString& endpoint_id) const { - return PeerLabelForEndpoint(endpoint_id); -} - -void NearbyTrayController::clearTransfers() { - transfers_.clear(); - transfer_row_for_payload_.clear(); - emit transfersChanged(); -} - -void NearbyTrayController::hideToTray() { - emit requestTrayMessage( - QStringLiteral("Nearby Tray"), - QStringLiteral("App is still running in the system tray.")); -} - -void NearbyTrayController::startSendMode() { - discovered_devices_.clear(); - emit discoveredDevicesChanged(); - auto discovery_options = BuildDiscoveryOptions(); - LogLine(QStringLiteral("ble: %1, bluetooth: %2, wifi_lan: %3, wifi_hotspot: $4").arg( - discovery_options.allowed_mediums.ble - ).arg( - discovery_options.allowed_mediums.bluetooth - ).arg( - discovery_options.allowed_mediums.wifi_lan).arg(discovery_options.allowed_mediums.wifi_hotspot) - ); - auto discovery_listener = BuildDiscoveryListener(); - service_.StartDiscovery( - service_id_,discovery_options, discovery_listener, - [this](NearbyConnectionsQtFacade::Status status) { - QMetaObject::invokeMethod( - this, - [this, status]() { - SetStatus(QStringLiteral("StartDiscovery: %1") - .arg(StatusToString(status))); - LogLine(QStringLiteral("StartDiscovery: %1") - .arg(StatusToString(status))); - if (status != NearbyConnectionsQtFacade::Status::kSuccess) { - running_ = false; - emit runningChanged(); - } - }, - Qt::QueuedConnection); - }); -} - -void NearbyTrayController::startReceiveMode() { - auto advert_options = BuildAdvertisingOptions(); - LogLine(QStringLiteral("ble: %1, bluetooth: %2, wifi_lan: %3, wifi_hotspot: %4").arg( - advert_options.allowed_mediums.ble - ).arg( - advert_options.allowed_mediums.bluetooth - ).arg( - advert_options.allowed_mediums.wifi_lan - ).arg(advert_options.allowed_mediums.wifi_hotspot)); - service_.StartAdvertising( - service_id_, BuildEndpointInfo(), BuildAdvertisingOptions(), - BuildConnectionListener(), - [this](NearbyConnectionsQtFacade::Status status) { - QMetaObject::invokeMethod( - this, - [this, status]() { - SetStatus(QStringLiteral("StartAdvertising: %1") - .arg(StatusToString(status))); - LogLine(QStringLiteral("StartAdvertising: %1") - .arg(StatusToString(status))); - if (status != NearbyConnectionsQtFacade::Status::kSuccess) { - running_ = false; - emit runningChanged(); - } - }, - Qt::QueuedConnection); - }); -} - -std::vector NearbyTrayController::BuildEndpointInfo() const { - QByteArray endpoint = device_name_.toUtf8(); - return std::vector(endpoint.begin(), endpoint.end()); -} - -NearbyConnectionsQtFacade::ConnectionListener -NearbyTrayController::BuildConnectionListener() { - NearbyConnectionsQtFacade::ConnectionListener listener; - listener.initiated_cb = - [this](const std::string& endpoint_id, - const NearbyConnectionsQtFacade::ConnectionInfo& info) { - QMetaObject::invokeMethod( - this, - [this, endpoint = QString::fromStdString(endpoint_id), - incoming = info.is_incoming_connection, - peer_name = QString::fromStdString(info.peer_name)]() { - SetPeerNameForEndpoint(endpoint, peer_name); - const QString peer = PeerLabelForEndpoint(endpoint); - LogLine(QStringLiteral("Connection initiated endpoint=%1 incoming=%2") - .arg(endpoint) - .arg(incoming)); - if (incoming) { - AddPendingConnection(endpoint); - SetStatus( - QStringLiteral("Incoming connection from %1").arg(peer)); - if (auto_accept_incoming_) { - acceptIncoming(endpoint); - } - } else { - acceptIncoming(endpoint); - } - }, - Qt::QueuedConnection); - }; - - listener.accepted_cb = [this](const std::string& endpoint_id) { - QMetaObject::invokeMethod( - this, - [this, endpoint = QString::fromStdString(endpoint_id)]() { - const QString peer = PeerLabelForEndpoint(endpoint); - AddConnectedDevice(endpoint); - RemovePendingConnection(endpoint); - SetStatus(QStringLiteral("Connected to %1").arg(peer)); - LogLine(QStringLiteral("Connection accepted endpoint=%1 peer=%2") - .arg(endpoint, peer)); - }, - Qt::QueuedConnection); - }; - - listener.rejected_cb = - [this](const std::string& endpoint_id, NearbyConnectionsQtFacade::Status status) { - QMetaObject::invokeMethod( - this, - [this, endpoint = QString::fromStdString(endpoint_id), status]() { - const QString peer = PeerLabelForEndpoint(endpoint); - RemovePendingConnection(endpoint); - SetStatus(QStringLiteral("Connection rejected by %1 (%2)") - .arg(peer, StatusToString(status))); - LogLine(QStringLiteral("Connection rejected endpoint=%1 status=%2") - .arg(endpoint, StatusToString(status))); - }, - Qt::QueuedConnection); - }; - - listener.disconnected_cb = [this](const std::string& endpoint_id) { - QMetaObject::invokeMethod( - this, - [this, endpoint = QString::fromStdString(endpoint_id)]() { - const QString peer = PeerLabelForEndpoint(endpoint); - RemoveConnectedDevice(endpoint); - RemovePendingConnection(endpoint); - endpoint_peer_names_.remove(endpoint); - endpoint_mediums_.remove(endpoint); - emit endpointMediumsChanged(); - SetStatus(QStringLiteral("Disconnected from %1").arg(peer)); - LogLine(QStringLiteral("Disconnected endpoint=%1").arg(endpoint)); - }, - Qt::QueuedConnection); - }; - - listener.bandwidth_changed_cb = - [this](const std::string& endpoint_id, NearbyConnectionsQtFacade::Medium medium) { - QMetaObject::invokeMethod( - this, - [this, endpoint = QString::fromStdString(endpoint_id), medium]() { - const QString medium_name = MediumToString(medium); - endpoint_mediums_[endpoint] = medium_name; - emit endpointMediumsChanged(); - UpdateTransferMediumForEndpoint(endpoint, medium_name); - LogLine(QStringLiteral("Bandwidth changed endpoint=%1 medium=%2") - .arg(endpoint, medium_name)); - }, - Qt::QueuedConnection); - }; - return listener; -} - -NearbyConnectionsQtFacade::DiscoveryListener -NearbyTrayController::BuildDiscoveryListener() { - NearbyConnectionsQtFacade::DiscoveryListener listener; - listener.endpoint_found_cb = - [this](const std::string& endpoint_id, - const NearbyConnectionsQtFacade::DiscoveredEndpointInfo& info) { - QMetaObject::invokeMethod( - this, - [this, endpoint = QString::fromStdString(endpoint_id), - peer_name = QString::fromStdString(info.peer_name)]() { - SetPeerNameForEndpoint(endpoint, peer_name); - AddDiscoveredDevice(endpoint); - LogLine(QStringLiteral("Discovered endpoint=%1 peer=%2") - .arg(endpoint, PeerLabelForEndpoint(endpoint))); - }, - Qt::QueuedConnection); - }; - listener.endpoint_lost_cb = [this](const std::string& endpoint_id) { - QMetaObject::invokeMethod( - this, - [this, endpoint = QString::fromStdString(endpoint_id)]() { - RemoveDiscoveredDevice(endpoint); - endpoint_peer_names_.remove(endpoint); - LogLine(QStringLiteral("Lost endpoint=%1").arg(endpoint)); - }, - Qt::QueuedConnection); - }; - listener.endpoint_distance_changed_cb = - [this](const std::string& endpoint_id, NearbyConnectionsQtFacade::DistanceInfo info) { - QMetaObject::invokeMethod( - this, - [this, endpoint = QString::fromStdString(endpoint_id), info]() { - LogLine(QStringLiteral("Distance changed endpoint=%1 value=%2") - .arg(endpoint) - .arg(static_cast(info))); - }, - Qt::QueuedConnection); - }; - return listener; -} - -NearbyConnectionsQtFacade::PayloadListener -NearbyTrayController::BuildPayloadListener() { - NearbyConnectionsQtFacade::PayloadListener listener; - listener.payload_cb = - [this](const std::string& endpoint_id, - NearbyConnectionsQtFacade::Payload payload) { - QMetaObject::invokeMethod( - this, - [this, endpoint = QString::fromStdString(endpoint_id), - payload = std::move(payload)]() { - if (payload.type == NearbyConnectionsQtFacade::Payload::Type::kBytes) { - const auto& bytes = payload.bytes; - const QString text = QString::fromUtf8( - reinterpret_cast(bytes.data()), - static_cast(bytes.size())); - - // Check if this is a FILE: metadata message (arrives before file) - if (text.startsWith(QStringLiteral("FILE:"))) { - QString filename = text.mid(5).trimmed(); - if (!filename.isEmpty()) { - pending_file_names_[endpoint] = filename; - LogLine(QStringLiteral("Received file metadata endpoint=%1 name=%2") - .arg(endpoint, filename)); - } - } - - emit payloadReceived(endpoint, QStringLiteral("bytes"), text); - LogLine(QStringLiteral("Received bytes payload endpoint=%1 id=%2 size=%3") - .arg(endpoint) - .arg(payload.id) - .arg(bytes.size())); - } else if (payload.type == - NearbyConnectionsQtFacade::Payload::Type::kFile) { - const QString path = QString::fromStdString(payload.file_path); - QString file_name = - QString::fromStdString(payload.file_name); - - // Use pending filename if available - if (pending_file_names_.contains(endpoint)) { - file_name = pending_file_names_.take(endpoint); - } - - const QString final_path = - FinalizeReceivedFilePath(path, file_name, payload.id); - emit payloadReceived(endpoint, QStringLiteral("file"), - final_path); - LogLine(QStringLiteral( - "Received file payload endpoint=%1 id=%2 path=%3 saved=%4 name=%5") - .arg(endpoint) - .arg(payload.id) - .arg(path, final_path, file_name)); - } - }, - Qt::QueuedConnection); - }; - - listener.payload_progress_cb = - [this](const std::string& endpoint_id, - const NearbyConnectionsQtFacade::PayloadTransferUpdate& update) { - QMetaObject::invokeMethod( - this, - [this, endpoint = QString::fromStdString(endpoint_id), - update]() { - QString direction = QStringLiteral("incoming"); - if (transfer_row_for_payload_.contains(update.payload_id)) { - const int row = transfer_row_for_payload_.value(update.payload_id); - if (row >= 0 && row < transfers_.size()) { - const QVariantMap transfer = transfers_[row].toMap(); - const QString existing_direction = - transfer.value(QStringLiteral("direction")).toString(); - if (!existing_direction.isEmpty()) { - direction = existing_direction; - } - } - } - UpsertTransfer(endpoint, update.payload_id, - PayloadStatusToString(update.status), - update.bytes_transferred, update.total_bytes, - direction); - }, - Qt::QueuedConnection); - }; - return listener; -} - -NearbyConnectionsQtFacade::MediumSelection -NearbyTrayController::BuildMediumSelection() const { - NearbyConnectionsQtFacade::MediumSelection selection; - selection.bluetooth = bluetooth_enabled_; - selection.ble = ble_enabled_; - selection.wifi_lan = wifi_lan_enabled_; - selection.wifi_hotspot = wifi_hotspot_enabled_; - selection.web_rtc = web_rtc_enabled_; - return selection; -} - -NearbyConnectionsQtFacade::AdvertisingOptions -NearbyTrayController::BuildAdvertisingOptions() const { - NearbyConnectionsQtFacade::AdvertisingOptions options; - options.strategy = StrategyFromName(connection_strategy_); - options.allowed_mediums = BuildMediumSelection(); - options.auto_upgrade_bandwidth = true; - options.enable_bluetooth_listening = true; - options.enforce_topology_constraints = true; - return options; -} - -NearbyConnectionsQtFacade::DiscoveryOptions NearbyTrayController::BuildDiscoveryOptions() - const { - NearbyConnectionsQtFacade::DiscoveryOptions options; - options.strategy = StrategyFromName(connection_strategy_); - options.allowed_mediums = BuildMediumSelection(); - return options; -} - -NearbyConnectionsQtFacade::ConnectionOptions NearbyTrayController::BuildConnectionOptions() - const { - NearbyConnectionsQtFacade::ConnectionOptions options; - options.allowed_mediums = BuildMediumSelection(); - options.non_disruptive_hotspot_mode = true; - return options; -} - -void NearbyTrayController::AddDiscoveredDevice(const QString& endpoint_id) { - if (discovered_devices_.contains(endpoint_id)) { - return; - } - discovered_devices_.append(endpoint_id); - emit discoveredDevicesChanged(); -} - -void NearbyTrayController::RemoveDiscoveredDevice(const QString& endpoint_id) { - if (!discovered_devices_.removeOne(endpoint_id)) { - return; - } - emit discoveredDevicesChanged(); -} - -void NearbyTrayController::AddConnectedDevice(const QString& endpoint_id) { - if (connected_devices_.contains(endpoint_id)) { - return; - } - connected_devices_.append(endpoint_id); - emit connectedDevicesChanged(); -} - -void NearbyTrayController::RemoveConnectedDevice(const QString& endpoint_id) { - if (!connected_devices_.removeOne(endpoint_id)) { - return; - } - emit connectedDevicesChanged(); -} - -void NearbyTrayController::AddPendingConnection(const QString& endpoint_id) { - if (pending_connections_.contains(endpoint_id)) { - return; - } - pending_connections_.append(endpoint_id); - emit pendingConnectionsChanged(); -} - -void NearbyTrayController::RemovePendingConnection(const QString& endpoint_id) { - if (!pending_connections_.removeOne(endpoint_id)) { - return; - } - emit pendingConnectionsChanged(); -} - -void NearbyTrayController::SetPeerNameForEndpoint(const QString& endpoint_id, - const QString& peer_name) { - const QString endpoint = endpoint_id.trimmed(); - if (endpoint.isEmpty()) { - return; - } - const QString previous = endpoint_peer_names_.value(endpoint).trimmed(); - const QString trimmed_name = peer_name.trimmed(); - if (trimmed_name.isEmpty()) { - if (previous.isEmpty()) { - return; - } - endpoint_peer_names_.remove(endpoint); - emit discoveredDevicesChanged(); - emit connectedDevicesChanged(); - emit pendingConnectionsChanged(); - return; - } - if (previous == trimmed_name) { - return; - } - endpoint_peer_names_[endpoint] = trimmed_name; - emit discoveredDevicesChanged(); - emit connectedDevicesChanged(); - emit pendingConnectionsChanged(); -} - -QString NearbyTrayController::PeerLabelForEndpoint( - const QString& endpoint_id) const { - const QString endpoint = endpoint_id.trimmed(); - if (endpoint.isEmpty()) { - return QStringLiteral("Unknown device"); - } - const QString peer_name = endpoint_peer_names_.value(endpoint).trimmed(); - return peer_name.isEmpty() ? QStringLiteral("Unknown device") : peer_name; -} - -QString NearbyTrayController::FinalizeReceivedFilePath( - const QString& received_path, const QString& received_file_name, - qlonglong payload_id) const { - const QString source = received_path.trimmed(); - if (source.isEmpty()) { - return source; - } - - QFileInfo source_info(source); - const QString source_abs = source_info.absoluteFilePath(); - const QString source_dir = source_info.absolutePath(); - - QString target_name = QFileInfo(received_file_name.trimmed()).fileName(); - if (target_name.isEmpty()) { - target_name = source_info.fileName(); - } - if (target_name.isEmpty()) { - target_name = QStringLiteral("payload_%1.bin").arg(payload_id); - } - - const QFileInfo target_name_info(target_name); - const QString stem = - target_name_info.completeBaseName().isEmpty() - ? target_name_info.fileName() - : target_name_info.completeBaseName(); - const QString suffix = target_name_info.completeSuffix(); - QString target_path = QDir(source_dir).filePath(target_name); - - int suffix_index = 1; - while (target_path != source_abs && QFileInfo::exists(target_path)) { - const QString next_name = - suffix.isEmpty() - ? QStringLiteral("%1_%2").arg(stem).arg(suffix_index) - : QStringLiteral("%1_%2.%3").arg(stem).arg(suffix_index).arg( - suffix); - target_path = QDir(source_dir).filePath(next_name); - ++suffix_index; - } - - if (target_path == source_abs) { - return source_abs; - } - - if (QFile::rename(source_abs, target_path)) { - return target_path; - } - - if (QFile::copy(source_abs, target_path)) { - QFile::remove(source_abs); - return target_path; - } - - return source_abs; -} - -void NearbyTrayController::UpsertTransfer(const QString& endpoint_id, - qlonglong payload_id, - const QString& status, - qulonglong bytes_transferred, - qulonglong total_bytes, - const QString& direction) { - const QString medium = mediumForEndpoint(endpoint_id); - const double progress = - total_bytes > 0 - ? static_cast(bytes_transferred) / - static_cast(total_bytes) - : 0.0; - - QVariantMap transfer{ - {QStringLiteral("payloadId"), payload_id}, - {QStringLiteral("endpointId"), endpoint_id}, - {QStringLiteral("status"), status}, - {QStringLiteral("bytesTransferred"), - static_cast(bytes_transferred)}, - {QStringLiteral("totalBytes"), static_cast(total_bytes)}, - {QStringLiteral("progress"), progress}, - {QStringLiteral("medium"), medium}, - {QStringLiteral("direction"), direction}, - }; - - if (transfer_row_for_payload_.contains(payload_id)) { - const int row = transfer_row_for_payload_.value(payload_id); - if (row >= 0 && row < transfers_.size()) { - transfers_[row] = transfer; - emit transfersChanged(); - return; - } - } - - transfer_row_for_payload_.insert(payload_id, transfers_.size()); - transfers_.append(transfer); - emit transfersChanged(); -} - -void NearbyTrayController::UpdateTransferMediumForEndpoint( - const QString& endpoint_id, const QString& medium) { - bool changed = false; - for (int i = 0; i < transfers_.size(); ++i) { - QVariantMap row = transfers_[i].toMap(); - if (row.value(QStringLiteral("endpointId")).toString() != endpoint_id) { - continue; - } - row[QStringLiteral("medium")] = medium; - transfers_[i] = row; - changed = true; - } - if (changed) { - emit transfersChanged(); - } -} - -void NearbyTrayController::SetStatus(const QString& status) { - if (status == status_message_) { - return; - } - status_message_ = status; - emit statusMessageChanged(); - LogLine(QStringLiteral("Status: %1").arg(status_message_)); -} - -void NearbyTrayController::LogLine(const QString& line) { - if (!log_file_.isOpen()) { - ReopenLogFile(); - } - if (!log_file_.isOpen()) { - return; - } - QTextStream stream(&log_file_); - stream << QDateTime::currentDateTimeUtc().toString(Qt::ISODate) - << " " << line << "\n"; - stream.flush(); -} - -void NearbyTrayController::ReopenLogFile() { - if (log_file_.isOpen()) { - log_file_.close(); - } - log_file_.setFileName(log_path_); - log_file_.open(QIODevice::Append | QIODevice::Text | QIODevice::WriteOnly); -} - -QString NearbyTrayController::StatusToString(NearbyConnectionsQtFacade::Status status) { - switch (status) { - case NearbyConnectionsQtFacade::Status::kSuccess: - return QStringLiteral("Success"); - case NearbyConnectionsQtFacade::Status::kError: - return QStringLiteral("Error"); - case NearbyConnectionsQtFacade::Status::kOutOfOrderApiCall: - return QStringLiteral("OutOfOrderApiCall"); - case NearbyConnectionsQtFacade::Status::kAlreadyHaveActiveStrategy: - return QStringLiteral("AlreadyHaveActiveStrategy"); - case NearbyConnectionsQtFacade::Status::kAlreadyAdvertising: - return QStringLiteral("AlreadyAdvertising"); - case NearbyConnectionsQtFacade::Status::kAlreadyDiscovering: - return QStringLiteral("AlreadyDiscovering"); - case NearbyConnectionsQtFacade::Status::kAlreadyListening: - return QStringLiteral("AlreadyListening"); - case NearbyConnectionsQtFacade::Status::kEndpointIOError: - return QStringLiteral("EndpointIOError"); - case NearbyConnectionsQtFacade::Status::kEndpointUnknown: - return QStringLiteral("EndpointUnknown"); - case NearbyConnectionsQtFacade::Status::kConnectionRejected: - return QStringLiteral("ConnectionRejected"); - case NearbyConnectionsQtFacade::Status::kAlreadyConnectedToEndpoint: - return QStringLiteral("AlreadyConnectedToEndpoint"); - case NearbyConnectionsQtFacade::Status::kNotConnectedToEndpoint: - return QStringLiteral("NotConnectedToEndpoint"); - case NearbyConnectionsQtFacade::Status::kBluetoothError: - return QStringLiteral("BluetoothError"); - case NearbyConnectionsQtFacade::Status::kBleError: - return QStringLiteral("BleError"); - case NearbyConnectionsQtFacade::Status::kWifiLanError: - return QStringLiteral("WifiLanError"); - case NearbyConnectionsQtFacade::Status::kPayloadUnknown: - return QStringLiteral("PayloadUnknown"); - case NearbyConnectionsQtFacade::Status::kReset: - return QStringLiteral("Reset"); - case NearbyConnectionsQtFacade::Status::kTimeout: - return QStringLiteral("Timeout"); - case NearbyConnectionsQtFacade::Status::kUnknown: - return QStringLiteral("Unknown"); - case NearbyConnectionsQtFacade::Status::kNextValue: - return QStringLiteral("NextValue"); - } - return QStringLiteral("Unknown"); -} - -QString NearbyTrayController::PayloadStatusToString( - NearbyConnectionsQtFacade::PayloadStatus status) { - switch (status) { - case NearbyConnectionsQtFacade::PayloadStatus::kSuccess: - return QStringLiteral("Success"); - case NearbyConnectionsQtFacade::PayloadStatus::kFailure: - return QStringLiteral("Failure"); - case NearbyConnectionsQtFacade::PayloadStatus::kInProgress: - return QStringLiteral("InProgress"); - case NearbyConnectionsQtFacade::PayloadStatus::kCanceled: - return QStringLiteral("Canceled"); - } - return QStringLiteral("Unknown"); -} - -QString NearbyTrayController::MediumToString(NearbyConnectionsQtFacade::Medium medium) { - switch (medium) { - case NearbyConnectionsQtFacade::Medium::kUnknown: - return QStringLiteral("Unknown"); - case NearbyConnectionsQtFacade::Medium::kMdns: - return QStringLiteral("mDNS"); - case NearbyConnectionsQtFacade::Medium::kBluetooth: - return QStringLiteral("Bluetooth"); - case NearbyConnectionsQtFacade::Medium::kWifiHotspot: - return QStringLiteral("WiFiHotspot"); - case NearbyConnectionsQtFacade::Medium::kBle: - return QStringLiteral("BLE"); - case NearbyConnectionsQtFacade::Medium::kWifiLan: - return QStringLiteral("WiFiLAN"); - case NearbyConnectionsQtFacade::Medium::kWifiAware: - return QStringLiteral("WiFiAware"); - case NearbyConnectionsQtFacade::Medium::kNfc: - return QStringLiteral("NFC"); - case NearbyConnectionsQtFacade::Medium::kWifiDirect: - return QStringLiteral("WiFiDirect"); - case NearbyConnectionsQtFacade::Medium::kWebRtc: - return QStringLiteral("WebRTC"); - case NearbyConnectionsQtFacade::Medium::kBleL2Cap: - return QStringLiteral("BLEL2CAP"); - } - return QStringLiteral("Unknown"); -} diff --git a/sharing/linux/qml_tray_app/nearby_tray_controller.h b/sharing/linux/qml_tray_app/nearby_tray_controller.h deleted file mode 100644 index 257e3a63..00000000 --- a/sharing/linux/qml_tray_app/nearby_tray_controller.h +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef SHARING_LINUX_QML_TRAY_APP_NEARBY_TRAY_CONTROLLER_H_ -#define SHARING_LINUX_QML_TRAY_APP_NEARBY_TRAY_CONTROLLER_H_ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "sharing/linux/nearby_connections_qt_facade.h" - -using NearbyConnectionsQtFacade = nearby::sharing::NearbyConnectionsQtFacade; - -class NearbyTrayController : public QObject { - Q_OBJECT - Q_PROPERTY(QString mode READ mode WRITE setMode NOTIFY modeChanged) - Q_PROPERTY(QString deviceName READ deviceName WRITE setDeviceName NOTIFY deviceNameChanged) - Q_PROPERTY(QString serviceId READ serviceId WRITE setServiceId NOTIFY serviceIdChanged) - Q_PROPERTY(QString mediumsMode READ mediumsMode WRITE setMediumsMode NOTIFY mediumsModeChanged) - Q_PROPERTY(bool bluetoothEnabled READ bluetoothEnabled WRITE setBluetoothEnabled NOTIFY bluetoothEnabledChanged) - Q_PROPERTY(bool bleEnabled READ bleEnabled WRITE setBleEnabled NOTIFY bleEnabledChanged) - Q_PROPERTY(bool wifiLanEnabled READ wifiLanEnabled WRITE setWifiLanEnabled NOTIFY wifiLanEnabledChanged) - Q_PROPERTY(bool wifiHotspotEnabled READ wifiHotspotEnabled WRITE setWifiHotspotEnabled NOTIFY wifiHotspotEnabledChanged) - Q_PROPERTY(bool webRtcEnabled READ webRtcEnabled WRITE setWebRtcEnabled NOTIFY webRtcEnabledChanged) - Q_PROPERTY(bool autoAcceptIncoming READ autoAcceptIncoming WRITE setAutoAcceptIncoming NOTIFY autoAcceptIncomingChanged) - Q_PROPERTY(QString connectionStrategy READ connectionStrategy WRITE setConnectionStrategy NOTIFY connectionStrategyChanged) - Q_PROPERTY(QString statusMessage READ statusMessage NOTIFY statusMessageChanged) - Q_PROPERTY(bool running READ running NOTIFY runningChanged) - Q_PROPERTY(QString logPath READ logPath WRITE setLogPath NOTIFY logPathChanged) - Q_PROPERTY(QStringList discoveredDevices READ discoveredDevices NOTIFY discoveredDevicesChanged) - Q_PROPERTY(QStringList connectedDevices READ connectedDevices NOTIFY connectedDevicesChanged) - Q_PROPERTY(QStringList pendingConnections READ pendingConnections NOTIFY pendingConnectionsChanged) - Q_PROPERTY(QVariantMap endpointMediums READ endpointMediums NOTIFY endpointMediumsChanged) - Q_PROPERTY(QVariantList transfers READ transfers NOTIFY transfersChanged) - - public: - explicit NearbyTrayController(QObject* parent = nullptr); - ~NearbyTrayController() override; - - QString mode() const { return mode_; } - void setMode(const QString& mode); - - QString deviceName() const { return device_name_; } - void setDeviceName(const QString& device_name); - - QString serviceId() const { return QString::fromStdString(service_id_); } - void setServiceId(const QString& service_id); - - QString mediumsMode() const { return mediums_mode_; } - void setMediumsMode(const QString& mode); - - bool bluetoothEnabled() const { return bluetooth_enabled_; } - void setBluetoothEnabled(bool enabled); - - bool bleEnabled() const { return ble_enabled_; } - void setBleEnabled(bool enabled); - - bool wifiLanEnabled() const { return wifi_lan_enabled_; } - void setWifiLanEnabled(bool enabled); - - bool wifiHotspotEnabled() const { return wifi_hotspot_enabled_; } - void setWifiHotspotEnabled(bool enabled); - - bool webRtcEnabled() const { return web_rtc_enabled_; } - void setWebRtcEnabled(bool enabled); - - bool autoAcceptIncoming() const { return auto_accept_incoming_; } - void setAutoAcceptIncoming(bool enabled); - - QString connectionStrategy() const { return connection_strategy_; } - void setConnectionStrategy(const QString& strategy); - - QString statusMessage() const { return status_message_; } - bool running() const { return running_; } - - QString logPath() const { return log_path_; } - void setLogPath(const QString& path); - - QStringList discoveredDevices() const { return discovered_devices_; } - QStringList connectedDevices() const { return connected_devices_; } - QStringList pendingConnections() const { return pending_connections_; } - QVariantMap endpointMediums() const { return endpoint_mediums_; } - QVariantList transfers() const { return transfers_; } - - Q_INVOKABLE void start(); - Q_INVOKABLE void stop(); - Q_INVOKABLE void connectToDevice(const QString& endpoint_id); - Q_INVOKABLE void disconnectDevice(const QString& endpoint_id); - Q_INVOKABLE void acceptIncoming(const QString& endpoint_id); - Q_INVOKABLE void rejectIncoming(const QString& endpoint_id); - Q_INVOKABLE void sendText(const QString& endpoint_id, const QString& text); - Q_INVOKABLE void initiateBandwidthUpgrade(const QString& endpoint_id); - Q_INVOKABLE QString mediumForEndpoint(const QString& endpoint_id) const; - Q_INVOKABLE QString peerNameForEndpoint(const QString& endpoint_id) const; - Q_INVOKABLE void clearTransfers(); - Q_INVOKABLE void hideToTray(); - - signals: - void modeChanged(); - void deviceNameChanged(); - void serviceIdChanged(); - void mediumsModeChanged(); - void bluetoothEnabledChanged(); - void bleEnabledChanged(); - void wifiLanEnabledChanged(); - void wifiHotspotEnabledChanged(); - void webRtcEnabledChanged(); - void autoAcceptIncomingChanged(); - void connectionStrategyChanged(); - void statusMessageChanged(); - void runningChanged(); - void logPathChanged(); - void discoveredDevicesChanged(); - void connectedDevicesChanged(); - void pendingConnectionsChanged(); - void endpointMediumsChanged(); - void transfersChanged(); - - void payloadReceived(const QString& endpoint_id, const QString& type, - const QString& value); - void requestTrayMessage(const QString& title, const QString& body); - - private: - void startSendMode(); - void startReceiveMode(); - void LoadSettings(); - void SaveSettings() const; - - std::vector BuildEndpointInfo() const; - - NearbyConnectionsQtFacade::ConnectionListener BuildConnectionListener(); - NearbyConnectionsQtFacade::DiscoveryListener BuildDiscoveryListener(); - NearbyConnectionsQtFacade::PayloadListener BuildPayloadListener(); - - NearbyConnectionsQtFacade::AdvertisingOptions BuildAdvertisingOptions() const; - NearbyConnectionsQtFacade::DiscoveryOptions BuildDiscoveryOptions() const; - NearbyConnectionsQtFacade::ConnectionOptions BuildConnectionOptions() const; - NearbyConnectionsQtFacade::MediumSelection BuildMediumSelection() const; - - void AddDiscoveredDevice(const QString& endpoint_id); - void RemoveDiscoveredDevice(const QString& endpoint_id); - void AddConnectedDevice(const QString& endpoint_id); - void RemoveConnectedDevice(const QString& endpoint_id); - void AddPendingConnection(const QString& endpoint_id); - void RemovePendingConnection(const QString& endpoint_id); - void SetPeerNameForEndpoint(const QString& endpoint_id, - const QString& peer_name); - QString PeerLabelForEndpoint(const QString& endpoint_id) const; - QString FinalizeReceivedFilePath(const QString& received_path, - const QString& received_file_name, - qlonglong payload_id) const; - - void UpsertTransfer(const QString& endpoint_id, qlonglong payload_id, - const QString& status, qulonglong bytes_transferred, - qulonglong total_bytes, const QString& direction); - void UpdateTransferMediumForEndpoint(const QString& endpoint_id, - const QString& medium); - - void SetStatus(const QString& status); - void LogLine(const QString& line); - void ReopenLogFile(); - - static QString StatusToString(NearbyConnectionsQtFacade::Status status); - static QString PayloadStatusToString( - NearbyConnectionsQtFacade::PayloadStatus status); - static QString MediumToString(NearbyConnectionsQtFacade::Medium medium); - - NearbyConnectionsQtFacade service_; - - QString mode_ = QStringLiteral("Receive"); - QString device_name_ = QStringLiteral("NearbyQt"); - std::string service_id_ = "com.nearby.qml.tray"; - QString mediums_mode_ = QStringLiteral("balanced"); - QString connection_strategy_ = QStringLiteral("P2pCluster"); - QString status_message_ = QStringLiteral("Idle"); - bool running_ = false; - - bool bluetooth_enabled_ = true; - bool ble_enabled_ = true; - bool wifi_lan_enabled_ = true; - bool wifi_hotspot_enabled_ = true; - bool web_rtc_enabled_ = false; - bool auto_accept_incoming_ = false; - - QString log_path_ = QStringLiteral("/tmp/nearby_qml_tray.log"); - QFile log_file_; - - QStringList discovered_devices_; - QStringList connected_devices_; - QStringList pending_connections_; - QHash endpoint_peer_names_; - QVariantMap endpoint_mediums_; - QVariantList transfers_; - QHash transfer_row_for_payload_; - QHash pending_file_names_; -}; - -#endif // SHARING_LINUX_QML_TRAY_APP_NEARBY_TRAY_CONTROLLER_H_ diff --git a/sharing/linux/qml_tray_app/resources.qrc b/sharing/linux/qml_tray_app/resources.qrc deleted file mode 100644 index 741bd3af..00000000 --- a/sharing/linux/qml_tray_app/resources.qrc +++ /dev/null @@ -1,9 +0,0 @@ - - - Main.qml - - - tray_icon.png - tray_icon-symbolic.svg - -