LCOV - code coverage report
Current view: top level - media/server/ipc/source - SessionManagementServer.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 87.0 % 92 80
Test Date: 2026-09-11 17:36:12 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<IMediaKeysModuleServiceFactory> &mediaKeysModuleFactory,
      49              :     const std::shared_ptr<IMediaKeysCapabilitiesModuleServiceFactory> &mediaKeysCapabilitiesModuleFactory,
      50              :     const std::shared_ptr<IWebAudioPlayerModuleServiceFactory> &webAudioPlayerModuleFactory,
      51              :     const std::shared_ptr<IPrivateMetricsModuleServiceFactory> &privateMetricsModuleFactory,
      52              :     const std::shared_ptr<IControlModuleServiceFactory> &controlModuleFactory, service::IPlaybackService &playbackService,
      53           10 :     service::ICdmService &cdmService, service::IControlService &controlService)
      54           10 :     : m_linuxWrapper{linuxWrapper}, m_isRunning{false},
      55           10 :       m_mediaPipelineModule{mediaPipelineModuleFactory->create(playbackService.getMediaPipelineService())},
      56           10 :       m_mediaPipelineCapabilitiesModule{
      57           10 :           mediaPipelineCapabilitiesModuleFactory->create(playbackService.getMediaPipelineService())},
      58           10 :       m_mediaKeysModule{mediaKeysModuleFactory->create(cdmService)},
      59           10 :       m_mediaKeysCapabilitiesModule{mediaKeysCapabilitiesModuleFactory->create(cdmService)},
      60           10 :       m_webAudioPlayerModule{webAudioPlayerModuleFactory->create(playbackService.getWebAudioPlayerService())},
      61           10 :       m_privateMetricsModule{privateMetricsModuleFactory->create(playbackService.getPrivateMetricsService())},
      62           30 :       m_controlModule{controlModuleFactory->create(playbackService, controlService)}
      63              : {
      64           10 :     m_ipcServer = ipcFactory->create();
      65              : }
      66              : 
      67           20 : SessionManagementServer::~SessionManagementServer()
      68              : {
      69           10 :     stop();
      70           10 :     if (m_ipcServerThread.joinable())
      71              :     {
      72            1 :         m_ipcServerThread.join();
      73              :     }
      74           10 :     if (m_socketFd >= 0)
      75              :     {
      76            2 :         if (::close(m_socketFd) != 0)
      77            2 :             RIALTO_SERVER_LOG_SYS_ERROR(errno, "Failed to close socket file descriptor");
      78              :     }
      79           20 : }
      80              : 
      81            0 : size_t SessionManagementServer::getBufferSizeForPasswordStructureCalls() const
      82              : {
      83              :     // Can return -1 on error
      84            0 :     return sysconf(_SC_GETPW_R_SIZE_MAX);
      85              : }
      86              : 
      87            6 : bool SessionManagementServer::initialize(const std::string &socketName, unsigned int socketPermissions,
      88              :                                          const std::string &socketOwner, const std::string &socketGroup)
      89              : {
      90            6 :     RIALTO_SERVER_LOG_INFO("Initializing Session Management Server. Socket name: '%s'", socketName.c_str());
      91            6 :     if (!m_ipcServer)
      92              :     {
      93            0 :         RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - Ipc server instance is NULL");
      94            0 :         return false;
      95              :     }
      96              : 
      97              :     // add a socket for clients and associate with a streamer object
      98           18 :     if (!m_ipcServer->addSocket(socketName,
      99           12 :                                 std::bind(&SessionManagementServer::onClientConnected, this, std::placeholders::_1),
     100           12 :                                 std::bind(&SessionManagementServer::onClientDisconnected, this, std::placeholders::_1)))
     101              :     {
     102            1 :         RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - can't add socket '%s' to the ipc "
     103              :                                 "server",
     104              :                                 socketName.c_str());
     105            1 :         return false;
     106              :     }
     107              : 
     108            5 :     common::setFilePermissions(socketName, socketPermissions);
     109            5 :     common::setFileOwnership(socketName, socketOwner, socketGroup);
     110              : 
     111            5 :     RIALTO_SERVER_LOG_MIL("Session Management Server initialized");
     112              : 
     113            5 :     return true;
     114              : }
     115              : 
     116            3 : bool SessionManagementServer::initialize(int32_t socketFd)
     117              : {
     118              :     // Rialto IPC library closes the file descriptor when the message handler finishes, so we need to duplicate the file
     119              :     // descriptor to keep it open for the lifetime of the server.
     120            3 :     m_socketFd = m_linuxWrapper->fcntl(socketFd, F_DUPFD_CLOEXEC, 3);
     121            3 :     if (m_socketFd < 0)
     122              :     {
     123            1 :         RIALTO_SERVER_LOG_SYS_ERROR(errno, "Failed to duplicate socket file descriptor");
     124            1 :         return false;
     125              :     }
     126            2 :     RIALTO_SERVER_LOG_INFO("Initializing Session Management Server. Socket fd: %d", m_socketFd);
     127            2 :     if (!m_ipcServer)
     128              :     {
     129            0 :         RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - Ipc server instance is NULL");
     130            0 :         return false;
     131              :     }
     132              : 
     133              :     // add a socket for clients and associate with a streamer object
     134            6 :     if (!m_ipcServer->addSocket(m_socketFd,
     135            4 :                                 std::bind(&SessionManagementServer::onClientConnected, this, std::placeholders::_1),
     136            4 :                                 std::bind(&SessionManagementServer::onClientDisconnected, this, std::placeholders::_1)))
     137              :     {
     138            1 :         RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - can't add socket fd %d to the ipc "
     139              :                                 "server",
     140              :                                 m_socketFd);
     141            1 :         return false;
     142              :     }
     143              : 
     144            1 :     RIALTO_SERVER_LOG_MIL("Session Management Server initialized");
     145              : 
     146            1 :     return true;
     147              : }
     148              : 
     149            1 : void SessionManagementServer::start()
     150              : {
     151            1 :     if (m_isRunning.load())
     152              :     {
     153            0 :         RIALTO_SERVER_LOG_DEBUG("Server is already in running state");
     154            0 :         return;
     155              :     }
     156            1 :     RIALTO_SERVER_LOG_DEBUG("Starting Session Management Server event loop");
     157            1 :     m_isRunning.store(true);
     158            1 :     m_ipcServerThread = std::thread(
     159            2 :         [this]()
     160              :         {
     161            1 :             constexpr int kPollInterval{100};
     162            1 :             while (m_ipcServer->process() && m_isRunning.load())
     163              :             {
     164            0 :                 m_ipcServer->wait(kPollInterval);
     165              :             }
     166            1 :             RIALTO_SERVER_LOG_MIL("Session Management Server event loop finished.");
     167            1 :         });
     168              : }
     169              : 
     170           10 : void SessionManagementServer::stop()
     171              : {
     172           10 :     m_isRunning.store(false);
     173              : }
     174              : 
     175            1 : void SessionManagementServer::setLogLevels(RIALTO_DEBUG_LEVEL defaultLogLevels, RIALTO_DEBUG_LEVEL clientLogLevels,
     176              :                                            RIALTO_DEBUG_LEVEL ipcLogLevels, RIALTO_DEBUG_LEVEL commonLogLevels)
     177              : {
     178            1 :     m_setLogLevelsService.setLogLevels(defaultLogLevels, clientLogLevels, ipcLogLevels, commonLogLevels);
     179              : }
     180              : 
     181            0 : void SessionManagementServer::notifyApplicationStateChanged(ApplicationState newState)
     182              : {
     183            0 :     if (m_privateMetricsModule)
     184              :     {
     185            0 :         m_privateMetricsModule->notifyApplicationStateChanged(newState);
     186              :     }
     187              : }
     188              : 
     189            2 : void SessionManagementServer::onClientConnected(const std::shared_ptr<::firebolt::rialto::ipc::IClient> &client)
     190              : {
     191            2 :     RIALTO_SERVER_LOG_MIL("Client app connected");
     192            2 :     m_controlModule->clientConnected(client);
     193            2 :     m_mediaPipelineModule->clientConnected(client);
     194            2 :     m_mediaPipelineCapabilitiesModule->clientConnected(client);
     195            2 :     m_mediaKeysModule->clientConnected(client);
     196            2 :     m_mediaKeysCapabilitiesModule->clientConnected(client);
     197            2 :     m_webAudioPlayerModule->clientConnected(client);
     198            2 :     m_privateMetricsModule->clientConnected(client);
     199            2 :     m_setLogLevelsService.clientConnected(client);
     200              : }
     201              : 
     202            1 : void SessionManagementServer::onClientDisconnected(const std::shared_ptr<::firebolt::rialto::ipc::IClient> &client)
     203              : {
     204            1 :     RIALTO_SERVER_LOG_MIL("Client app disconnected");
     205            1 :     m_setLogLevelsService.clientDisconnected(client);
     206            1 :     m_mediaKeysCapabilitiesModule->clientDisconnected(client);
     207            1 :     m_mediaKeysModule->clientDisconnected(client);
     208            1 :     m_mediaPipelineCapabilitiesModule->clientDisconnected(client);
     209            1 :     m_mediaPipelineModule->clientDisconnected(client);
     210            1 :     m_webAudioPlayerModule->clientDisconnected(client);
     211            1 :     m_privateMetricsModule->clientDisconnected(client);
     212            1 :     m_controlModule->clientDisconnected(client);
     213              : }
     214              : } // namespace firebolt::rialto::server::ipc
        

Generated by: LCOV version 2.0-1