/*
* Copyright (C) 2014-2015 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
// Qt
#include
// local
#include "application_manager.h"
#include "debughelpers.h"
#include "sessionmanager.h"
// QPA mirserver
#include "nativeinterface.h"
#include "mirserver.h"
#include "sessionlistener.h"
#include "logging.h"
#include "promptsessionlistener.h"
// mir
#include
#include
Q_LOGGING_CATEGORY(QTMIR_SESSIONS, "qtmir.sessions")
namespace ms = mir::scene;
namespace qtmir {
SessionManager *SessionManager::the_session_manager = nullptr;
void connectToSessionListener(SessionManager *manager, SessionListener *listener)
{
QObject::connect(listener, &SessionListener::sessionStarting,
manager, &SessionManager::onSessionStarting);
QObject::connect(listener, &SessionListener::sessionStopping,
manager, &SessionManager::onSessionStopping);
}
void connectToPromptSessionListener(SessionManager * manager, PromptSessionListener * listener)
{
QObject::connect(listener, &PromptSessionListener::promptSessionStarting,
manager, &SessionManager::onPromptSessionStarting);
QObject::connect(listener, &PromptSessionListener::promptSessionStopping,
manager, &SessionManager::onPromptSessionStopping);
QObject::connect(listener, &PromptSessionListener::promptProviderAdded,
manager, &SessionManager::onPromptProviderAdded);
QObject::connect(listener, &PromptSessionListener::promptProviderRemoved,
manager, &SessionManager::onPromptProviderRemoved);
}
SessionManager* SessionManager::singleton()
{
if (!the_session_manager) {
NativeInterface *nativeInterface = dynamic_cast(QGuiApplication::platformNativeInterface());
if (!nativeInterface) {
qCritical("ERROR: Unity.Application QML plugin requires use of the 'mirserver' QPA plugin");
QGuiApplication::quit();
return nullptr;
}
SessionListener *sessionListener = static_cast(nativeInterface->nativeResourceForIntegration("SessionListener"));
PromptSessionListener *promptSessionListener = static_cast(nativeInterface->nativeResourceForIntegration("PromptSessionListener"));
the_session_manager = new SessionManager(nativeInterface->m_mirServer, ApplicationManager::singleton());
connectToSessionListener(the_session_manager, sessionListener);
connectToPromptSessionListener(the_session_manager, promptSessionListener);
}
return the_session_manager;
}
SessionManager::SessionManager(
const QSharedPointer& mirServer,
ApplicationManager* applicationManager,
QObject *parent)
: SessionModel(parent)
, m_mirServer(mirServer)
, m_applicationManager(applicationManager)
{
qCDebug(QTMIR_SESSIONS) << "SessionManager::SessionManager - this=" << this;
setObjectName("qtmir::SessionManager");
}
SessionManager::~SessionManager()
{
qCDebug(QTMIR_SESSIONS) << "SessionManager::~SessionManager - this=" << this;
}
SessionInterface *SessionManager::findSession(const mir::scene::Session* session) const
{
if (!session) return nullptr;
for (SessionInterface* child : list()) {
if (child->session().get() == session)
return child;
}
return nullptr;
}
void SessionManager::onSessionStarting(std::shared_ptr const& session)
{
qCDebug(QTMIR_SESSIONS) << "SessionManager::onSessionStarting - sessionName=" << session->name().c_str();
Session* qmlSession = new Session(session,
m_mirServer->the_prompt_session_manager());
insert(0, qmlSession);
Application* application = m_applicationManager->findApplicationWithSession(session);
if (application && application->state() != Application::Running) {
application->setSession(qmlSession);
}
// need to remove if we've destroyed outside
connect(qmlSession, &Session::destroyed, this, [&](QObject *item) {
auto sessionToRemove = static_cast(item);
remove(sessionToRemove);
});
Q_EMIT sessionStarting(qmlSession);
}
void SessionManager::onSessionStopping(std::shared_ptr const& session)
{
qCDebug(QTMIR_SESSIONS) << "SessionManager::onSessionStopping - sessionName=" << session->name().c_str();
SessionInterface* qmlSession = findSession(session.get());
if (!qmlSession) return;
remove(qmlSession);
qmlSession->setLive(false);
Q_EMIT sessionStopping(qmlSession);
}
void SessionManager::onPromptSessionStarting(const std::shared_ptr& promptSession)
{
qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptSessionStarting - promptSession=" << promptSession.get();
std::shared_ptr appSession = m_mirServer->the_prompt_session_manager()->application_for(promptSession);
SessionInterface *qmlAppSession = findSession(appSession.get());
if (qmlAppSession) {
m_mirPromptToSessionHash[promptSession.get()] = qmlAppSession;
qmlAppSession->appendPromptSession(promptSession);
} else {
qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptSessionStarting - could not find app session for prompt session";
}
}
void SessionManager::onPromptSessionStopping(const std::shared_ptr& promptSession)
{
qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptSessionStopping - promptSession=" << promptSession.get();
for (SessionInterface *qmlSession : this->list()) {
qmlSession->removePromptSession(promptSession);
}
m_mirPromptToSessionHash.remove(promptSession.get());
}
void SessionManager::onPromptProviderAdded(const mir::scene::PromptSession *promptSession,
const std::shared_ptr &promptProvider)
{
qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - promptSession=" << promptSession << " promptProvider=" << promptProvider.get();
SessionInterface* qmlAppSession = m_mirPromptToSessionHash.value(promptSession, nullptr);
if (!qmlAppSession) {
qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - could not find session item for app session";
return;
}
SessionInterface* qmlPromptProvider = findSession(promptProvider.get());
if (!qmlPromptProvider) {
qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - could not find session item for provider session";
return;
}
qmlAppSession->addChildSession(qmlPromptProvider);
}
void SessionManager::onPromptProviderRemoved(const mir::scene::PromptSession *promptSession,
const std::shared_ptr &promptProvider)
{
qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderRemoved - promptSession=" << promptSession << " promptProvider=" << promptProvider.get();
SessionInterface* qmlPromptProvider = findSession(promptProvider.get());
if (!qmlPromptProvider) {
qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - could not find session item for provider session";
return;
}
qmlPromptProvider->setLive(false);
}
} // namespace qtmir