From a03b614e64f7410e22e08f6f8e15689951df5b9c Mon Sep 17 00:00:00 2001 From: kkostiuk Date: Tue, 19 Oct 2021 15:55:34 -0400 Subject: [PATCH] connectivity: implement for macOS Change-Id: I1295a55c1c633f4e193b6097c12bdd7435dffade --- CMakeLists.txt | 11 +++++- src/connectivitymonitor.cpp | 15 +------- src/connectivitymonitor.mm | 76 +++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 src/connectivitymonitor.mm diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f88333c..6c9bec7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,6 @@ set(COMMON_SOURCES ${SRC_DIR}/smartlistmodel.cpp ${SRC_DIR}/utils.cpp ${SRC_DIR}/rendermanager.cpp - ${SRC_DIR}/connectivitymonitor.cpp ${SRC_DIR}/mainapplication.cpp ${SRC_DIR}/messagesadapter.cpp ${SRC_DIR}/accountadapter.cpp @@ -218,6 +217,8 @@ if (${QT_VERSION_MAJOR} STRLESS 6) endif() if(MSVC) + list(APPEND COMMON_SOURCES + ${SRC_DIR}/connectivitymonitor.cpp) # preprocessor defines add_definitions(-DUNICODE -DQT_NO_DEBUG -DNDEBUG) @@ -268,7 +269,8 @@ if(MSVC) elseif (NOT APPLE) list(APPEND COMMON_SOURCES ${SRC_DIR}/xrectsel.c - ${SRC_DIR}/dbuserrorhandler.cpp) + ${SRC_DIR}/dbuserrorhandler.cpp + ${SRC_DIR}/connectivitymonitor.cpp) list(APPEND COMMON_HEADERS ${SRC_DIR}/dbuserrorhandler.h ${SRC_DIR}/xrectsel.h) @@ -348,6 +350,9 @@ elseif (NOT APPLE) find_library(qrencode qrencode) find_library(X11 X11) else() + list(APPEND COMMON_SOURCES + ${SRC_DIR}/connectivitymonitor.mm) + find_package(PkgConfig REQUIRED) if(NOT DEFINED LRC) if(EXISTS ${PROJECT_SOURCE_DIR}/../install/lrc) set(LRC ${PROJECT_SOURCE_DIR}/../install/lrc) @@ -383,6 +388,7 @@ else() set(JAMI_DATA_PREFIX "${CMAKE_INSTALL_PREFIX}/share") find_library(ringclient ringclient ${LRCLIBDIR} NO_DEFAULT_PATH) + find_library(SYSTEM_CONFIGURATUION SystemConfiguration) endif() # Qt find package @@ -604,6 +610,7 @@ else() target_link_libraries(${PROJECT_NAME} PRIVATE ${QML_LIBS} ${LRC_LIB_NAME} + ${SYSTEM_CONFIGURATUION} qrencode) # translations diff --git a/src/connectivitymonitor.cpp b/src/connectivitymonitor.cpp index b02410df..af51846f 100644 --- a/src/connectivitymonitor.cpp +++ b/src/connectivitymonitor.cpp @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -#if !defined(_WIN32) && !defined(__APPLE__) +#ifndef _WIN32 #include #include #ifdef USE_LIBNM @@ -165,19 +165,6 @@ ConnectivityMonitor::~ConnectivityMonitor() destroy(); CoUninitialize(); } -#elif defined(Q_OS_MACOS) -ConnectivityMonitor::ConnectivityMonitor(QObject* parent) - : QObject(parent) -{} -bool -ConnectivityMonitor::isOnline() -{ - return false; -} -ConnectivityMonitor::~ConnectivityMonitor() -{ - qDebug() << "Destroying connectivity monitor"; -} #else #ifdef USE_LIBNM static void diff --git a/src/connectivitymonitor.mm b/src/connectivitymonitor.mm new file mode 100644 index 00000000..9f7e291b --- /dev/null +++ b/src/connectivitymonitor.mm @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 by Savoir-faire Linux + * Author: Kateryna Kostiuk + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "connectivitymonitor.h" +#include + +dispatch_queue_t scNetworkQueue; +SCNetworkReachabilityRef currentReachability; + +static void ReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkConnectionFlags flags, void* info) +{ + void (^callbackBlock)(SCNetworkReachabilityFlags) = (void (^)(SCNetworkReachabilityFlags))info; + callbackBlock(flags); +} + +ConnectivityMonitor::ConnectivityMonitor(QObject* parent) + : QObject(parent) +{ + scNetworkQueue = dispatch_queue_create("scNetworkReachability", DISPATCH_QUEUE_SERIAL); + SCNetworkReachabilityRef reachabilityRef = NULL; + void (^callbackBlock)(SCNetworkReachabilityFlags) = ^(SCNetworkReachabilityFlags flags) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + Q_EMIT connectivityChanged(); + }); + }; + + SCNetworkReachabilityContext context = { + .version = 0, + .info = [callbackBlock copy], + .release = CFRelease + }; + reachabilityRef = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, "test"); + if (SCNetworkReachabilitySetCallback(reachabilityRef , ReachabilityCallback, &context)) { + if (!SCNetworkReachabilitySetDispatchQueue(reachabilityRef, scNetworkQueue) ) { + SCNetworkReachabilitySetCallback(reachabilityRef, NULL, NULL); + } + currentReachability = reachabilityRef; + } +} + +ConnectivityMonitor::~ConnectivityMonitor() +{ + SCNetworkReachabilitySetCallback(currentReachability, NULL, NULL); + currentReachability = NULL; + qDebug() << "Destroying connectivity monitor"; +} + +bool +ConnectivityMonitor::isOnline() +{ + SCNetworkReachabilityFlags flags; + SCNetworkReachabilityRef reachabilityRef = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, "test"); + auto valid = SCNetworkReachabilityGetFlags(reachabilityRef, &flags); + bool isConnected = (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired); + CFRelease(reachabilityRef); + return valid && isConnected; +}