From f19bd0d4ba8f832a8cc2ac0fc02b47407eb415f3 Mon Sep 17 00:00:00 2001 From: Mate Barany Date: Tue, 4 Jul 2023 17:48:13 +0200 Subject: [PATCH] Create QML Binding for Qt Network Information Create QML Binding for the QNetworkInformation C++ class. Task-number: QTBUG-113813 Change-Id: Ia9889d261735434adba4bfdf4fe338d99117247b Reviewed-by: Ulf Hermann --- src/CMakeLists.txt | 4 ++ src/qmlnetwork/CMakeLists.txt | 23 ++++++ src/qmlnetwork/doc/qtqmlnetwork.qdocconf | 34 +++++++++ .../doc/src/qtqmlnetwork-qmltypes.qdoc | 32 +++++++++ src/qmlnetwork/doc/src/qtqmlnetwork.qdoc | 23 ++++++ src/qmlnetwork/qqmlnetworkinformation.cpp | 24 +++++++ src/qmlnetwork/qqmlnetworkinformation.qdoc | 70 +++++++++++++++++++ src/qmlnetwork/qqmlnetworkinformation_p.h | 40 +++++++++++ tests/auto/CMakeLists.txt | 1 + tests/auto/qmlnetwork/CMakeLists.txt | 4 ++ .../qqmlnetworkinformation/CMakeLists.txt | 39 +++++++++++ .../data/tst_networkinformation.qml | 14 ++++ .../tst_qqmlnetworkinformation.cpp | 51 ++++++++++++++ 13 files changed, 359 insertions(+) create mode 100644 src/qmlnetwork/CMakeLists.txt create mode 100644 src/qmlnetwork/doc/qtqmlnetwork.qdocconf create mode 100644 src/qmlnetwork/doc/src/qtqmlnetwork-qmltypes.qdoc create mode 100644 src/qmlnetwork/doc/src/qtqmlnetwork.qdoc create mode 100644 src/qmlnetwork/qqmlnetworkinformation.cpp create mode 100644 src/qmlnetwork/qqmlnetworkinformation.qdoc create mode 100644 src/qmlnetwork/qqmlnetworkinformation_p.h create mode 100644 tests/auto/qmlnetwork/CMakeLists.txt create mode 100644 tests/auto/qmlnetwork/qqmlnetworkinformation/CMakeLists.txt create mode 100644 tests/auto/qmlnetwork/qqmlnetworkinformation/data/tst_networkinformation.qml create mode 100644 tests/auto/qmlnetwork/qqmlnetworkinformation/tst_qqmlnetworkinformation.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7196674a92..f531959035 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,10 @@ add_subdirectory(qmlmodels) add_subdirectory(core) +if (QT_FEATURE_qml_network) + add_subdirectory(qmlnetwork) +endif() + if(QT_FEATURE_qml_worker_script) add_subdirectory(qmlworkerscript) endif() diff --git a/src/qmlnetwork/CMakeLists.txt b/src/qmlnetwork/CMakeLists.txt new file mode 100644 index 0000000000..5e998c57cb --- /dev/null +++ b/src/qmlnetwork/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_qml_module(QmlNetwork + URI "QtNetwork" + VERSION "${PROJECT_VERSION}" + DESIGNER_SUPPORTED + DEPENDENCIES + QtQml/auto + SOURCES + qqmlnetworkinformation_p.h + qqmlnetworkinformation.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Network + Qt::Qml + GENERATE_CPP_EXPORTS + GENERATE_PRIVATE_CPP_EXPORTS +) + +qt_internal_add_docs(QmlNetwork + doc/qtqmlnetwork.qdocconf +) diff --git a/src/qmlnetwork/doc/qtqmlnetwork.qdocconf b/src/qmlnetwork/doc/qtqmlnetwork.qdocconf new file mode 100644 index 0000000000..d2ea4ff28a --- /dev/null +++ b/src/qmlnetwork/doc/qtqmlnetwork.qdocconf @@ -0,0 +1,34 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) + +project = QtQmlNetwork +description = Qt QML Network Reference Documentation +version = $QT_VERSION + +qhp.projects = QtQmlNetwork + +qhp.QtQmlNetwork.file = qtqmlnetwork.qhp +qhp.QtQmlNetwork.namespace = org.qt-project.qtqmlnetwork.$QT_VERSION_TAG +qhp.QtQmlNetwork.virtualFolder = qtqmlnetwork +qhp.QtQmlNetwork.indexTitle = Qt QML Network +qhp.QtQmlNetwork.indexRoot = + +qhp.QtQmlNetwork.subprojects = qmltypes +qhp.QtQmlNetwork.subprojects.qmltypes.title = QML Types +qhp.QtQmlNetwork.subprojects.qmltypes.indexTitle = Qt QML Network QML Types +qhp.QtQmlNetwork.subprojects.qmltypes.selectors = qmlclass +qhp.QtQmlNetwork.subprojects.qmltypes.sortPages = true + +depends = qtcore qtdoc qtqml qtnetwork + +# This module has no documented C++ types, clear the module header +moduleheader = + +headerdirs += ../ +sourcedirs += ../ + +imagedirs += images + +navigation.landingpage = "Qt QML Network" +navigation.qmltypespage = "Qt QML Network QML Types" + +tagfile = qtqmlnetwork.tags diff --git a/src/qmlnetwork/doc/src/qtqmlnetwork-qmltypes.qdoc b/src/qmlnetwork/doc/src/qtqmlnetwork-qmltypes.qdoc new file mode 100644 index 0000000000..f28ab17a3f --- /dev/null +++ b/src/qmlnetwork/doc/src/qtqmlnetwork-qmltypes.qdoc @@ -0,0 +1,32 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \qmlmodule QtNetwork + \title Qt QML Network QML Types + \since 6.7 + \ingroup qmlmodules + \brief Provides core network functionality in QML. + + The Qt QML Network module provides core network functionality in QML. + + The QML types can be imported into your application using the + following import statement in your .qml file: + + \qml + import QtNetwork + \endqml + + \section1 QML Types + + \generatelist {qmltypesbymodule QtNetwork} + + \section1 Related Information + + \list + \li \l {Qt Network} + \li \l {Qt QML QML Types}{Base QML Types} + \endlist + + \noautolist +*/ diff --git a/src/qmlnetwork/doc/src/qtqmlnetwork.qdoc b/src/qmlnetwork/doc/src/qtqmlnetwork.qdoc new file mode 100644 index 0000000000..6f74cc1fb2 --- /dev/null +++ b/src/qmlnetwork/doc/src/qtqmlnetwork.qdoc @@ -0,0 +1,23 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page qtqmlnetwork-index.html + \title Qt QML Network + + \brief The Qt QML Network module provides core network functionality in QML. + + The module exposes the Qt C++ \l [QtNetwork] {Qt Network} {Network} + functionality to QML. + + \section1 QML Types + + \generatelist {qmltypesbymodule QtNetwork} + + \section1 Related Information + + \list + \li \l{Qt Network} + \li \l{Qt QML} + \endlist +*/ diff --git a/src/qmlnetwork/qqmlnetworkinformation.cpp b/src/qmlnetwork/qqmlnetworkinformation.cpp new file mode 100644 index 0000000000..bdfb2ea656 --- /dev/null +++ b/src/qmlnetwork/qqmlnetworkinformation.cpp @@ -0,0 +1,24 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qqmlnetworkinformation_p.h" + +QT_BEGIN_NAMESPACE + +QNetworkInformation *QQmlNetworkInformation::create(QQmlEngine *, QJSEngine *) +{ + static QNetworkInformation *s_singletonInstance = []() { + QNetworkInformation::loadDefaultBackend(); + QNetworkInformation *singletonInstance = QNetworkInformation::instance(); + + Q_ASSERT(singletonInstance); + QJSEngine::setObjectOwnership(singletonInstance, QJSEngine::CppOwnership); + return singletonInstance; + }(); + + return s_singletonInstance; +} + +QT_END_NAMESPACE + +#include "moc_qqmlnetworkinformation_p.cpp" diff --git a/src/qmlnetwork/qqmlnetworkinformation.qdoc b/src/qmlnetwork/qqmlnetworkinformation.qdoc new file mode 100644 index 0000000000..1628c6cbb3 --- /dev/null +++ b/src/qmlnetwork/qqmlnetworkinformation.qdoc @@ -0,0 +1,70 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \qmltype NetworkInformation + \inqmlmodule QtNetwork + \instantiates QNetworkInformation + \brief Provides a cross-platform interface to network-related information. + + NetworkInformation provides a cross-platform interface to network-related information. + + NetworkInformation is a singleton. + + \sa QNetworkInformation +*/ + +/*! + \qmlproperty enumeration NetworkInformation::reachability + \readonly + + Holds the current state of the system's network connectivity. + + \value NetworkInformation.Reachability.Unknown + Connection may be established but the OS has yet to confirm full + connectivity, or this feature is not supported. + \value NetworkInformation.Reachability.Disconnected + The system may not have connectivity at all. + \value NetworkInformation.Reachability.Local + The system is connected to a network, but might only be able to + access devices on the local network. + \value NetworkInformation.Reachability.Site + The system is connected to a network, but might only be able to + access devices on the local subnet or an intranet. + \value NetworkInformation.Reachability.Online + The system is connected to a network and able to access the Internet. +*/ + +/*! + \qmlproperty bool NetworkInformation::isBehindCaptivePortal + \readonly + + Indicates if the user's device is currently known to be behind a captive portal. +*/ + +/*! + \qmlproperty enumeration NetworkInformation::transportMedium + \readonly + + Holds the currently active transport medium for the application. + + \value NetworkInformation.TransportMedium.Unknown + If the OS reports no active medium, the active medium is not recognized by Qt, + or the TransportMedium feature is not supported. + \value NetworkInformation.TransportMedium.Ethernet + The currently active connection is using Ethernet. Note: This value may also be + returned when Windows is connected to a Bluetooth personal area network. + \value NetworkInformation.TransportMedium.Cellular + The currently active connection is using a cellular network. + \value NetworkInformation.TransportMedium.WiFi + The currently active connection is using Wi-Fi. + \value NetworkInformation.TransportMedium.Bluetooth + The currently active connection is connected using Bluetooth. +*/ + +/*! + \qmlproperty bool NetworkInformation::isMetered + \readonly + + Returns whether the current connection is (known to be) metered or not. +*/ diff --git a/src/qmlnetwork/qqmlnetworkinformation_p.h b/src/qmlnetwork/qqmlnetworkinformation_p.h new file mode 100644 index 0000000000..ba1c4c0d5e --- /dev/null +++ b/src/qmlnetwork/qqmlnetworkinformation_p.h @@ -0,0 +1,40 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QQMLNETWORKINFORMATION_P_H +#define QQMLNETWORKINFORMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +struct Q_QMLNETWORK_PRIVATE_EXPORT QQmlNetworkInformation +{ + Q_GADGET + QML_FOREIGN(QNetworkInformation) + QML_NAMED_ELEMENT(NetworkInformation) + QML_SINGLETON + +public: + static QNetworkInformation *create(QQmlEngine *, QJSEngine *); +}; + +QT_END_NAMESPACE + +#endif diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt index 74c4ee86d6..b47bd318d5 100644 --- a/tests/auto/CMakeLists.txt +++ b/tests/auto/CMakeLists.txt @@ -26,6 +26,7 @@ if(TARGET Qt::Quick) endif() if(TARGET Qt::QuickTest) add_subdirectory(core) + add_subdirectory(qmlnetwork) endif() add_subdirectory(toolsupport) if(NOT UIKIT AND NOT ANDROID AND NOT QNX) # FIXME: QTBUG-92591 QTBUG-100202 diff --git a/tests/auto/qmlnetwork/CMakeLists.txt b/tests/auto/qmlnetwork/CMakeLists.txt new file mode 100644 index 0000000000..3f6ae6d6f0 --- /dev/null +++ b/tests/auto/qmlnetwork/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +add_subdirectory(qqmlnetworkinformation) diff --git a/tests/auto/qmlnetwork/qqmlnetworkinformation/CMakeLists.txt b/tests/auto/qmlnetwork/qqmlnetworkinformation/CMakeLists.txt new file mode 100644 index 0000000000..a9554a9295 --- /dev/null +++ b/tests/auto/qmlnetwork/qqmlnetworkinformation/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qqmlnetworkinformation LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/tst_*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qqmlnetworkinformation + QMLTEST + SOURCES + tst_qqmlnetworkinformation.cpp + LIBRARIES + Qt::QmlPrivate + Qt::QuickTestUtilsPrivate + Qt::Network + TESTDATA ${test_data} +) + +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlnetworkinformation) +endif() + +qt_internal_extend_target(tst_qqmlnetworkinformation CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=":/data" +) + +qt_internal_extend_target(tst_qqmlnetworkinformation CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data" +) diff --git a/tests/auto/qmlnetwork/qqmlnetworkinformation/data/tst_networkinformation.qml b/tests/auto/qmlnetwork/qqmlnetworkinformation/data/tst_networkinformation.qml new file mode 100644 index 0000000000..ed6535cfb2 --- /dev/null +++ b/tests/auto/qmlnetwork/qqmlnetworkinformation/data/tst_networkinformation.qml @@ -0,0 +1,14 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQml +import QtNetwork + +QtObject { + property int local: NetworkInformation.Reachability.Local + property int reachability: NetworkInformation.reachability + property bool isBehindCaptivePortal: NetworkInformation.isBehindCaptivePortal + property int ethernet: NetworkInformation.TransportMedium.Ethernet + property int transportMedium: NetworkInformation.transportMedium + property bool isMetered: NetworkInformation.isMetered +} diff --git a/tests/auto/qmlnetwork/qqmlnetworkinformation/tst_qqmlnetworkinformation.cpp b/tests/auto/qmlnetwork/qqmlnetworkinformation/tst_qqmlnetworkinformation.cpp new file mode 100644 index 0000000000..f37a47873d --- /dev/null +++ b/tests/auto/qmlnetwork/qqmlnetworkinformation/tst_qqmlnetworkinformation.cpp @@ -0,0 +1,51 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include + +class tst_qqmlnetworkinformation : public QQmlDataTest +{ + Q_OBJECT + +public: + explicit tst_qqmlnetworkinformation() : QQmlDataTest(QT_QMLTEST_DATADIR) { } + +private Q_SLOTS: + void networkInformation(); +}; + +void tst_qqmlnetworkinformation::networkInformation() +{ + QNetworkInformation::loadDefaultBackend(); + QNetworkInformation *networkinfo = QNetworkInformation::instance(); +#if defined(Q_OS_LINUX) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN) + QVERIFY(networkinfo); +#else + QSKIP("Platform does not provide network information"); +#endif + + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("tst_networkinformation.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer object(component.create()); + QVERIFY(!object.isNull()); + + QCOMPARE(object->property("local").toInt(), + static_cast(QNetworkInformation::Reachability::Local)); + QCOMPARE(object->property("reachability").toInt(), + static_cast(networkinfo->reachability())); + QCOMPARE(object->property("isBehindCaptivePortal").toBool(), + networkinfo->isBehindCaptivePortal()); + QCOMPARE(object->property("ethernet").toInt(), + static_cast(QNetworkInformation::TransportMedium::Ethernet)); + QCOMPARE(object->property("transportMedium").toInt(), + static_cast(networkinfo->transportMedium())); + QCOMPARE(object->property("isMetered").toBool(), networkinfo->isMetered()); +} + +QTEST_MAIN(tst_qqmlnetworkinformation) + +#include "tst_qqmlnetworkinformation.moc"