Commit 40ae62c8 authored by Ghislain MARY's avatar Ghislain MARY

Allow handling of single application instance via DBus.

parent 2ce85954
......@@ -29,6 +29,7 @@ set(CMAKE_CXX_STANDARD 11)
set(ASSETS_DIR assets)
option(ENABLE_DBUS "Enable single instance handling via DBus." NO)
option(ENABLE_UPDATE_CHECK "Enable update check." NO)
include(GNUInstallDirs)
......@@ -77,6 +78,9 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -DQT_QML_DEBUG -DQT_
# ------------------------------------------------------------------------------
set(QT5_PACKAGES Core Gui Quick Widgets QuickControls2 Svg LinguistTools Concurrent Network)
if(ENABLE_DBUS)
list(APPEND QT5_PACKAGES DBus)
endif()
set(QT5_PACKAGES_OPTIONAL TextToSpeech)
if (LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
......@@ -138,7 +142,6 @@ set(SOURCES
src/components/telephone-numbers/TelephoneNumbersModel.cpp
src/components/timeline/TimelineModel.cpp
src/components/url-handlers/UrlHandlers.cpp
src/externals/single-application/SingleApplication.cpp
src/main.cpp
src/utils/LinphoneUtils.cpp
src/utils/Utils.cpp
......@@ -193,11 +196,18 @@ set(HEADERS
src/components/timeline/TimelineModel.hpp
src/components/url-handlers/UrlHandlers.hpp
src/externals/single-application/SingleApplication.hpp
src/externals/single-application/SingleApplicationPrivate.hpp
src/utils/LinphoneUtils.hpp
src/utils/Utils.hpp
)
if(ENABLE_DBUS)
list(APPEND SOURCES src/app/single-application/SingleApplicationDBus.cpp)
list(APPEND HEADERS src/app/single-application/SingleApplicationDBusPrivate.hpp)
else()
list(APPEND SOURCES src/externals/single-application/SingleApplication.cpp)
list(APPEND HEADERS src/externals/single-application/SingleApplicationPrivate.hpp)
endif()
set(QRC_RESOURCES resources.qrc)
set(LANGUAGES_DIRECTORY "${ASSETS_DIR}/languages")
......
......@@ -25,3 +25,7 @@ lcb_define_target("linphoneqt" "linphone" "ms2plugins")
if(NOT WIN32 AND NOT APPLE)
lcb_blacklist_dependencies("turbo-jpeg") # turbo-jpeg is already provided by Qt5 so do not build it
endif()
if(UNIX AND NOT APPLE)
lcb_add_option("DBus" "Enable handling of single application instance via DBus." OFF)
endif()
......@@ -26,5 +26,9 @@ lcb_dependencies("linphone" "ms2plugins")
lcb_groupable(YES)
lcb_cmake_options("-DENABLE_UPDATE_CHECK=${ENABLE_UPDATE_CHECK}")
if(UNIX AND NOT APPLE)
lcb_cmake_options("-DENABLE_DBUS=${ENABLE_DBUS}")
endif()
# Add config step for packaging
set(LINPHONE_BUILDER_ADDITIONAL_CONFIG_STEPS "${CMAKE_CURRENT_LIST_DIR}/additional_steps.cmake")
/*
* SingleApplicationDBus.cpp
* Copyright (C) 2017 Belledonne Communications, Grenoble, France
*
* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Created on: June 20, 2017
* Author: Ghislain MARY
*/
#include <cstdlib>
#include <iostream>
#include <QtCore/QByteArray>
#include <QtDBus/QtDBus>
#include "../../utils/Utils.hpp"
#include "../../externals/single-application/SingleApplication.hpp"
#include "SingleApplicationDBusPrivate.hpp"
// =============================================================================
const char *SERVICE_NAME = "org.linphone.SingleApplication";
SingleApplicationPrivate::SingleApplicationPrivate (SingleApplication *q_ptr)
: QDBusAbstractAdaptor(q_ptr), q_ptr(q_ptr) {
}
SingleApplicationPrivate::~SingleApplicationPrivate () {
}
QDBusConnection SingleApplicationPrivate::getBus () const {
if (options & SingleApplication::Mode::User) {
return QDBusConnection::sessionBus();
} else {
return QDBusConnection::systemBus();
}
}
void SingleApplicationPrivate::startPrimary () {
if (getBus().registerObject("/", this, QDBusConnection::ExportAllSlots) == false) {
qWarning() << "Failed to register single application object on DBus";
}
instanceNumber = 0;
}
void SingleApplicationPrivate::startSecondary () {
instanceNumber = 1;
}
SingleApplication::SingleApplication (int &argc, char *argv[], bool allowSecondary, Options options, int)
: QApplication(argc, argv), d_ptr(new SingleApplicationPrivate(this)) {
Q_D(SingleApplication);
// Store the current mode of the program
d->options = options;
if (!d->getBus().isConnected()) {
qWarning() << "Cannot connect to the D-Bus session bus.";
delete d;
::exit(EXIT_FAILURE);
}
if (d->getBus().registerService(SERVICE_NAME)) {
d->startPrimary();
return;
}
if (allowSecondary) {
d->startSecondary();
return;
}
delete d;
::exit(EXIT_SUCCESS);
}
SingleApplication::~SingleApplication () {
Q_D(SingleApplication);
delete d;
}
bool SingleApplication::isPrimary () {
Q_D(SingleApplication);
return d->instanceNumber == 0;
}
bool SingleApplication::isSecondary () {
Q_D(SingleApplication);
return d->instanceNumber != 0;
}
quint32 SingleApplication::instanceId () {
Q_D(SingleApplication);
return d->instanceNumber;
}
bool SingleApplication::sendMessage (QByteArray message, int timeout) {
Q_D(SingleApplication);
if (isPrimary()) return false;
QDBusInterface iface(SERVICE_NAME, "/", "", d->getBus());
if (iface.isValid()) {
iface.setTimeout(timeout);
QDBusMessage msg = iface.call(QDBus::Block, "messageReceived", instanceId(), message);
return true;
}
return false;
}
void SingleApplicationPrivate::messageReceived (quint32 instanceId, QByteArray message) {
Q_Q(SingleApplication);
Q_EMIT q->receivedMessage(instanceId, message);
}
/*
* SingleApplicationDBusPrivate.hpp
* Copyright (C) 2017 Belledonne Communications, Grenoble, France
*
* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Created on: June 20, 2017
* Author: Ghislain MARY
*/
#ifndef SINGLE_APPLICATION_DBUS_PRIVATE_H
#define SINGLE_APPLICATION_DBUS_PRIVATE_H
#include "../../externals/single-application/SingleApplication.hpp"
#include <QtDBus/QtDBus>
// =============================================================================
struct InstancesInfo {
bool primary;
quint32 secondary;
};
class SingleApplicationPrivate : public QDBusAbstractAdaptor {
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.linphone.DBus.SingleApplication")
public:
Q_DECLARE_PUBLIC(SingleApplication) SingleApplicationPrivate (SingleApplication *q_ptr);
~SingleApplicationPrivate ();
QDBusConnection getBus () const;
void startPrimary ();
void startSecondary ();
SingleApplication *q_ptr;
SingleApplication::Options options;
quint32 instanceNumber;
public Q_SLOTS:
void messageReceived(quint32 instanceId, QByteArray message);
};
#endif // SINGLE_APPLICATION_DBUS_PRIVATE_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment