LCOV - code coverage report
Current view: top level - media/server/ipc/source - SessionManagementServer.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 87.4 % 95 83
Test Date: 2026-09-29 14:28:21 Functions: 83.3 % 12 10

            Line data    Source code
       1              : /*
       2              :  * If not stated otherwise in this file or this component's LICENSE file the
       3              :  * following copyright and licenses apply:
       4              :  *
       5              :  * Copyright 2022 Sky UK
       6              :  *
       7              :  * Licensed under the Apache License, Version 2.0 (the "License");
       8              :  * you may not use this file except in compliance with the License.
       9              :  * You may obtain a copy of the License at
      10              :  *
      11              :  * http://www.apache.org/licenses/LICENSE-2.0
      12              :  *
      13              :  * Unless required by applicable law or agreed to in writing, software
      14              :  * distributed under the License is distributed on an "AS IS" BASIS,
      15              :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      16              :  * See the License for the specific language governing permissions and
      17              :  * limitations under the License.
      18              :  */
      19              : 
      20              : #include "SessionManagementServer.h"
      21              : #include "IControlModuleService.h"
      22              : #include "IMediaKeysCapabilitiesModuleService.h"
      23              : #include "IMediaKeysModuleService.h"
      24              : #include "IMediaPipelineModuleService.h"
      25              : #include "IPrivateMetricsModuleService.h"
      26              : #include "IWebAudioPlayerModuleService.h"
      27              : #include "LinuxUtils.h"
      28              : #include "RialtoServerLogging.h"
      29              : #include <IIpcServerFactory.h>
      30              : #include <grp.h>
      31              : #include <pwd.h>
      32              : #include <sys/stat.h>
      33              : #include <sys/types.h>
      34              : #include <unistd.h>
      35              : 
      36              : namespace
      37              : {
      38              : constexpr uid_t kNoOwnerChange = -1; // -1 means chown() won't change the owner
      39              : constexpr gid_t kNoGroupChange = -1; // -1 means chown() won't change the group
      40              : } // namespace
      41              : namespace firebolt::rialto::server::ipc
      42              : {
      43           10 : SessionManagementServer::SessionManagementServer(
      44              :     const std::shared_ptr<firebolt::rialto::wrappers::ILinuxWrapper> &linuxWrapper,
      45              :     const std::shared_ptr<firebolt::rialto::ipc::IServerFactory> &ipcFactory,
      46              :     const std::shared_ptr<IMediaPipelineModuleServiceFactory> &mediaPipelineModuleFactory,
      47              :     const std::shared_ptr<IMediaPipelineCapabilitiesModuleServiceFactory> &mediaPipelineCapabilitiesModuleFactory,
      48              :     const std::shared_ptr<IMediaCapabilitiesModuleServiceFactory> &mediaCapabilitiesModuleFactory,
      49              :     const std::shared_ptr<IMediaKeysModuleServiceFactory> &mediaKeysModuleFactory,
      50              :     const std::shared_ptr<IMediaKeysCapabilitiesModuleServiceFactory> &mediaKeysCapabilitiesModuleFactory,
      51              :     const std::shared_ptr<IWebAudioPlayerModuleServiceFactory> &webAudioPlayerModuleFactory,
      52              :     const std::shared_ptr<IPrivateMetricsModuleServiceFactory> &privateMetricsModuleFactory,
      53              :     const std::shared_ptr<IControlModuleServiceFactory> &controlModuleFactory, service::IPlaybackService &playbackService,
      54           10 :     service::ICdmService &cdmService, service::IControlService &controlService)
      55           10 :     : m_linuxWrapper{linuxWrapper}, m_isRunning{false},
      56           10 :       m_mediaPipelineModule{mediaPipelineModuleFactory->create(playbackService.getMediaPipelineService())},
      57           10 :       m_mediaPipelineCapabilitiesModule{
      58           10 :           mediaPipelineCapabilitiesModuleFactory->create(playbackService.getMediaPipelineService())},
      59           10 :       m_mediaCapabilitiesModule{mediaCapabilitiesModuleFactory->create(playbackService.getMediaPipelineService())},
      60           10 :       m_mediaKeysModule{mediaKeysModuleFactory->create(cdmService)},
      61           10 :       m_mediaKeysCapabilitiesModule{mediaKeysCapabilitiesModuleFactory->create(cdmService)},
      62           10 :       m_webAudioPlayerModule{webAudioPlayerModuleFactory->create(playbackService.getWebAudioPlayerService())},
      63           10 :       m_privateMetricsModule{privateMetricsModuleFactory->create(playbackService.getPrivateMetricsService())},
      64           30 :       m_controlModule{controlModuleFactory->create(playbackService, controlService)}
      65              : {
      66           10 :     m_ipcServer = ipcFactory->create();
      67              : }
      68              : 
      69           20 : SessionManagementServer::~SessionManagementServer()
      70              : {
      71           10 :     stop();
      72           10 :     if (m_ipcServerThread.joinable())
      73              :     {
      74            1 :         m_ipcServerThread.join();
      75              :     }
      76           10 :     if (m_socketFd >= 0)
      77              :     {
      78            2 :         if (::close(m_socketFd) != 0)
      79            2 :             RIALTO_SERVER_LOG_SYS_ERROR(errno, "Failed to close socket file descriptor");
      80              :     }
      81           20 : }
      82              : 
      83            0 : size_t SessionManagementServer::getBufferSizeForPasswordStructureCalls() const
      84              : {
      85              :     // Can return -1 on error
      86            0 :     return sysconf(_SC_GETPW_R_SIZE_MAX);
      87              : }
      88              : 
      89            6 : bool SessionManagementServer::initialize(const std::string &socketName, unsigned int socketPermissions,
      90              :                                          const std::string &socketOwner, const std::string &socketGroup)
      91              : {
      92            6 :     RIALTO_SERVER_LOG_INFO("Initializing Session Management Server. Socket name: '%s'", socketName.c_str());
      93            6 :     if (!m_ipcServer)
      94              :     {
      95            0 :         RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - Ipc server instance is NULL");
      96            0 :         return false;
      97              :     }
      98              : 
      99              :     // add a socket for clients and associate with a streamer object
     100           18 :     if (!m_ipcServer->addSocket(socketName,
     101           12 :                                 std::bind(&SessionManagementServer::onClientConnected, this, std::placeholders::_1),
     102           12 :                                 std::bind(&SessionManagementServer::onClientDisconnected, this, std::placeholders::_1)))
     103              :     {
     104            1 :         RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - can't add socket '%s' to the ipc "
     105              :                                 "server",
     106              :                                 socketName.c_str());
     107            1 :         return false;
     108              :     }
     109              : 
     110            5 :     common::setFilePermissions(socketName, socketPermissions);
     111            5 :     common::setFileOwnership(socketName, socketOwner, socketGroup);
     112              : 
     113            5 :     RIALTO_SERVER_LOG_MIL("Session Management Server initialized");
     114              : 
     115            5 :     return true;
     116              : }
     117              : 
     118            3 : bool SessionManagementServer::initialize(int32_t socketFd)
     119              : {
     120              :     // Rialto IPC library closes the file descriptor when the message handler finishes, so we need to duplicate the file
     121              :     // descriptor to keep it open for the lifetime of the server.
     122            3 :     m_socketFd = m_linuxWrapper->fcntl(socketFd, F_DUPFD_CLOEXEC, 3);
     123            3 :     if (m_socketFd < 0)
     124              :     {
     125            1 :         RIALTO_SERVER_LOG_SYS_ERROR(errno, "Failed to duplicate socket file descriptor");
     126            1 :         return false;
     127              :     }
     128            2 :     RIALTO_SERVER_LOG_INFO("Initializing Session Management Server. Socket fd: %d", m_socketFd);
     129            2 :     if (!m_ipcServer)
     130              :     {
     131            0 :         RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - Ipc server instance is NULL");
     132            0 :         return false;
     133              :     }
     134              : 
     135              :     // add a socket for clients and associate with a streamer object
     136            6 :     if (!m_ipcServer->addSocket(m_socketFd,
     137            4 :                                 std::bind(&SessionManagementServer::onClientConnected, this, std::placeholders::_1),
     138            4 :                                 std::bind(&SessionManagementServer::onClientDisconnected, this, std::placeholders::_1)))
     139              :     {
     140            1 :         RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - can't add socket fd %d to the ipc "
     141              :                                 "server",
     142              :                                 m_socketFd);
     143            1 :         return false;
     144              :     }
     145              : 
     146            1 :     RIALTO_SERVER_LOG_MIL("Session Management Server initialized");
     147              : 
     148            1 :     return true;
     149              : }
     150              : 
     151            1 : void SessionManagementServer::start()
     152              : {
     153            1 :     if (m_isRunning.load())
     154              :     {
     155            0 :         RIALTO_SERVER_LOG_DEBUG("Server is already in running state");
     156            0 :         return;
     157              :     }
     158            1 :     RIALTO_SERVER_LOG_DEBUG("Starting Session Management Server event loop");
     159            1 :     m_isRunning.store(true);
     160            1 :     m_ipcServerThread = std::thread(
     161            2 :         [this]()
     162              :         {
     163            1 :             constexpr int kPollInterval{100};
     164            1 :             while (m_ipcServer->process() && m_isRunning.load())
     165              :             {
     166            0 :                 m_ipcServer->wait(kPollInterval);
     167              :             }
     168            1 :             RIALTO_SERVER_LOG_MIL("Session Management Server event loop finished.");
     169            1 :         });
     170              : }
     171              : 
     172           10 : void SessionManagementServer::stop()
     173              : {
     174           10 :     m_isRunning.store(false);
     175              : }
     176              : 
     177            1 : void SessionManagementServer::setLogLevels(RIALTO_DEBUG_LEVEL defaultLogLevels, RIALTO_DEBUG_LEVEL clientLogLevels,
     178              :                                            RIALTO_DEBUG_LEVEL ipcLogLevels, RIALTO_DEBUG_LEVEL commonLogLevels)
     179              : {
     180            1 :     m_setLogLevelsService.setLogLevels(defaultLogLevels, clientLogLevels, ipcLogLevels, commonLogLevels);
     181              : }
     182              : 
     183            0 : void SessionManagementServer::notifyApplicationStateChanged(ApplicationState newState)
     184              : {
     185            0 :     if (m_privateMetricsModule)
     186              :     {
     187            0 :         m_privateMetricsModule->notifyApplicationStateChanged(newState);
     188              :     }
     189              : }
     190              : 
     191            2 : void SessionManagementServer::onClientConnected(const std::shared_ptr<::firebolt::rialto::ipc::IClient> &client)
     192              : {
     193            2 :     RIALTO_SERVER_LOG_MIL("Client app connected");
     194            2 :     m_controlModule->clientConnected(client);
     195            2 :     m_mediaPipelineModule->clientConnected(client);
     196            2 :     m_mediaPipelineCapabilitiesModule->clientConnected(client);
     197            2 :     m_mediaCapabilitiesModule->clientConnected(client);
     198            2 :     m_mediaKeysModule->clientConnected(client);
     199            2 :     m_mediaKeysCapabilitiesModule->clientConnected(client);
     200            2 :     m_webAudioPlayerModule->clientConnected(client);
     201            2 :     m_privateMetricsModule->clientConnected(client);
     202            2 :     m_setLogLevelsService.clientConnected(client);
     203              : }
     204              : 
     205            1 : void SessionManagementServer::onClientDisconnected(const std::shared_ptr<::firebolt::rialto::ipc::IClient> &client)
     206              : {
     207            1 :     RIALTO_SERVER_LOG_MIL("Client app disconnected");
     208            1 :     m_setLogLevelsService.clientDisconnected(client);
     209            1 :     m_mediaKeysCapabilitiesModule->clientDisconnected(client);
     210            1 :     m_mediaKeysModule->clientDisconnected(client);
     211            1 :     m_mediaCapabilitiesModule->clientDisconnected(client);
     212            1 :     m_mediaPipelineCapabilitiesModule->clientDisconnected(client);
     213            1 :     m_mediaPipelineModule->clientDisconnected(client);
     214            1 :     m_webAudioPlayerModule->clientDisconnected(client);
     215            1 :     m_privateMetricsModule->clientDisconnected(client);
     216            1 :     m_controlModule->clientDisconnected(client);
     217              : }
     218              : } // namespace firebolt::rialto::server::ipc
        

Generated by: LCOV version 2.0-1