From 68387e485c954d6db2cf423723883a0b6dae222c Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 4 May 2020 15:03:09 +0200 Subject: Android: Add support for proxies Pick-to: 5.15 Fixes: QTBUG-78812 Change-Id: Id1f35a5e4ca3d8841edae378df69b65ef599c1ca Reviewed-by: Alexandru Croitor --- src/network/.prev_CMakeLists.txt | 13 ++- src/network/CMakeLists.txt | 13 ++- src/network/android/jar/CMakeLists.txt | 16 +++ src/network/android/jar/jar.pro | 15 +++ .../qtproject/qt5/android/network/QtNetwork.java | 101 ++++++++++++++++++ src/network/kernel/kernel.pri | 6 +- src/network/kernel/qnetworkproxy_android.cpp | 118 +++++++++++++++++++++ 7 files changed, 279 insertions(+), 3 deletions(-) create mode 100644 src/network/android/jar/CMakeLists.txt create mode 100644 src/network/android/jar/jar.pro create mode 100644 src/network/android/jar/src/org/qtproject/qt5/android/network/QtNetwork.java create mode 100644 src/network/kernel/qnetworkproxy_android.cpp (limited to 'src/network') diff --git a/src/network/.prev_CMakeLists.txt b/src/network/.prev_CMakeLists.txt index bc088516a3..ecd3eebdc6 100644 --- a/src/network/.prev_CMakeLists.txt +++ b/src/network/.prev_CMakeLists.txt @@ -238,11 +238,22 @@ qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND UNIX AND NOT MACOS PkgConfig::Libproxy ) -qt_extend_target(Network CONDITION UNIX AND NOT MACOS AND NOT QT_FEATURE_libproxy +qt_extend_target(Network CONDITION ANDROID AND NOT QT_FEATURE_libproxy + SOURCES + kernel/qnetworkproxy_android.cpp +) + +qt_extend_target(Network CONDITION UNIX AND NOT ANDROID AND NOT MACOS AND NOT QT_FEATURE_libproxy SOURCES kernel/qnetworkproxy_generic.cpp ) +if(ANDROID AND (ANDROID)) + set_property(TARGET Network APPEND PROPERTY QT_ANDROID_BUNDLED_JAR_DEPENDENCIES + jar/QtAndroidNetwork.jar + ) +endif() + qt_extend_target(Network CONDITION QT_FEATURE_socks5 SOURCES socket/qsocks5socketengine.cpp socket/qsocks5socketengine_p.h diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 0aff359750..b0d18fab0a 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -238,11 +238,22 @@ qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND UNIX AND NOT MACOS PkgConfig::Libproxy ) -qt_extend_target(Network CONDITION UNIX AND NOT MACOS AND NOT QT_FEATURE_libproxy +qt_extend_target(Network CONDITION ANDROID + SOURCES + kernel/qnetworkproxy_android.cpp +) + +qt_extend_target(Network CONDITION UNIX AND NOT ANDROID AND NOT MACOS AND NOT QT_FEATURE_libproxy AND (UNIX OR WINRT) SOURCES kernel/qnetworkproxy_generic.cpp ) +if(ANDROID AND (ANDROID)) + set_property(TARGET Network APPEND PROPERTY QT_ANDROID_BUNDLED_JAR_DEPENDENCIES + jar/QtAndroidNetwork.jar + ) +endif() + qt_extend_target(Network CONDITION QT_FEATURE_socks5 SOURCES socket/qsocks5socketengine.cpp socket/qsocks5socketengine_p.h diff --git a/src/network/android/jar/CMakeLists.txt b/src/network/android/jar/CMakeLists.txt new file mode 100644 index 0000000000..5b7c2d012b --- /dev/null +++ b/src/network/android/jar/CMakeLists.txt @@ -0,0 +1,16 @@ +# Generated from jar.pro. + +set(java_sources + src/org/qtproject/qt5/android/network/QtNetwork.java +) + +add_jar(QtAndroidNetwork + INCLUDE_JARS ${QT_ANDROID_JAR} + SOURCES ${java_sources} +) + +install_jar(QtAndroidNetwork + DESTINATION jar + COMPONENT Devel +) + diff --git a/src/network/android/jar/jar.pro b/src/network/android/jar/jar.pro new file mode 100644 index 0000000000..4af1012c1c --- /dev/null +++ b/src/network/android/jar/jar.pro @@ -0,0 +1,15 @@ +CONFIG += single_arch + +TARGET = QtAndroidNetwork + +load(qt_build_paths) +CONFIG += java +DESTDIR = $$MODULE_BASE_OUTDIR/jar + +JAVACLASSPATH += $$PWD/src + +JAVASOURCES += $$PWD/src/org/qtproject/qt5/android/network/QtNetwork.java + +# install +target.path = $$[QT_INSTALL_PREFIX]/jar +INSTALLS += target diff --git a/src/network/android/jar/src/org/qtproject/qt5/android/network/QtNetwork.java b/src/network/android/jar/src/org/qtproject/qt5/android/network/QtNetwork.java new file mode 100644 index 0000000000..249ffe61a5 --- /dev/null +++ b/src/network/android/jar/src/org/qtproject/qt5/android/network/QtNetwork.java @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +package org.qtproject.qt5.android.network; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.util.Log; +import android.net.ConnectivityManager; +import android.net.Proxy; +import android.net.ProxyInfo; + +public class QtNetwork +{ + private static final String LOG_TAG = "QtNetwork"; + private static ProxyReceiver m_proxyReceiver = null; + private static final Object m_lock = new Object(); + private static ProxyInfo m_proxyInfo = null; + + private static class ProxyReceiver extends BroadcastReceiver + { + @Override + public void onReceive(Context context, Intent intent) + { + m_proxyInfo = null; + } + } + + private QtNetwork() {} + + public static void registerReceiver(final Context context) + { + synchronized (m_lock) { + if (m_proxyReceiver == null) { + m_proxyReceiver = new ProxyReceiver(); + IntentFilter intentFilter = new IntentFilter(Proxy.PROXY_CHANGE_ACTION); + context.registerReceiver(m_proxyReceiver, intentFilter); + } + } + } + + public static void unregisterReceiver(final Context context) + { + synchronized (m_lock) { + if (m_proxyReceiver == null) + return; + + context.unregisterReceiver(m_proxyReceiver); + } + } + + public static ConnectivityManager getConnectivityManager(final Context context) + { + return (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); + } + + public static ProxyInfo getProxyInfo(final Context context) + { + if (m_proxyInfo == null) + m_proxyInfo = (ProxyInfo)getConnectivityManager(context).getDefaultProxy(); + return m_proxyInfo; + } +} diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index d7d0dd522c..c726515d15 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -93,4 +93,8 @@ else: qtConfig(libproxy) { SOURCES += kernel/qnetworkproxy_libproxy.cpp QMAKE_USE_PRIVATE += libproxy libdl } -else:SOURCES += kernel/qnetworkproxy_generic.cpp +else:android: SOURCES += kernel/qnetworkproxy_android.cpp +else: SOURCES += kernel/qnetworkproxy_generic.cpp + +android: ANDROID_BUNDLED_JAR_DEPENDENCIES = \ + jar/QtAndroidNetwork.jar diff --git a/src/network/kernel/qnetworkproxy_android.cpp b/src/network/kernel/qnetworkproxy_android.cpp new file mode 100644 index 0000000000..ddfe86960f --- /dev/null +++ b/src/network/kernel/qnetworkproxy_android.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnetworkproxy.h" +#include +#include + +#ifndef QT_NO_NETWORKPROXY + +QT_BEGIN_NAMESPACE + +struct ProxyInfoObject +{ +public: + ProxyInfoObject(); + ~ProxyInfoObject(); +}; + +Q_GLOBAL_STATIC(ProxyInfoObject, proxyInfoInstance) + +static const char networkClass[] = "org/qtproject/qt5/android/network/QtNetwork"; + +ProxyInfoObject::ProxyInfoObject() +{ + QJNIObjectPrivate::callStaticMethod(networkClass, + "registerReceiver", + "(Landroid/content/Context;)V", + QtAndroidPrivate::context()); +} + +ProxyInfoObject::~ProxyInfoObject() +{ + QJNIObjectPrivate::callStaticMethod(networkClass, + "unregisterReceiver", + "(Landroid/content/Context;)V", + QtAndroidPrivate::context()); +} + +QList QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query) +{ + QList proxyList; + if (!proxyInfoInstance) + return proxyList; + + QJNIObjectPrivate proxyInfo = QJNIObjectPrivate::callStaticObjectMethod(networkClass, + "getProxyInfo", + "(Landroid/content/Context;)Landroid/net/ProxyInfo;", + QtAndroidPrivate::context()); + if (proxyInfo.isValid()) { + QJNIObjectPrivate exclusionList = proxyInfo.callObjectMethod("getExclusionList", + "()[Ljava/lang/String;"); + bool exclude = false; + if (exclusionList.isValid()) { + jobjectArray listObject = static_cast(exclusionList.object()); + QJNIEnvironmentPrivate env; + QJNIObjectPrivate entry; + const int size = env->GetArrayLength(listObject); + QUrl host = QUrl(query.url().host()); + for (int i = 0; i < size; ++i) { + entry = env->GetObjectArrayElement(listObject, i); + if (host.matches(QUrl(entry.toString()), QUrl::RemoveScheme)) { + exclude = true; + break; + } + } + } + if (!exclude) { + QJNIObjectPrivate hostName = proxyInfo.callObjectMethod("getHost"); + const int port = proxyInfo.callMethod("getPort"); + QNetworkProxy proxy(QNetworkProxy::HttpProxy, hostName.toString(), port); + proxyList << proxy; + } + } + if (proxyList.isEmpty()) + proxyList << QNetworkProxy::NoProxy; + + return proxyList; +} + +QT_END_NAMESPACE + +#endif -- cgit v1.2.3