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 "IWebAudioPlayerModuleService.h"
26 : #include "LinuxUtils.h"
27 : #include "RialtoServerLogging.h"
28 : #include <IIpcServerFactory.h>
29 : #include <grp.h>
30 : #include <pwd.h>
31 : #include <sys/stat.h>
32 : #include <sys/types.h>
33 : #include <unistd.h>
34 :
35 : namespace
36 : {
37 : constexpr uid_t kNoOwnerChange = -1; // -1 means chown() won't change the owner
38 : constexpr gid_t kNoGroupChange = -1; // -1 means chown() won't change the group
39 : } // namespace
40 : namespace firebolt::rialto::server::ipc
41 : {
42 9 : SessionManagementServer::SessionManagementServer(
43 : const std::shared_ptr<firebolt::rialto::ipc::IServerFactory> &ipcFactory,
44 : const std::shared_ptr<IMediaPipelineModuleServiceFactory> &mediaPipelineModuleFactory,
45 : const std::shared_ptr<IMediaPipelineCapabilitiesModuleServiceFactory> &mediaPipelineCapabilitiesModuleFactory,
46 : const std::shared_ptr<IMediaKeysModuleServiceFactory> &mediaKeysModuleFactory,
47 : const std::shared_ptr<IMediaKeysCapabilitiesModuleServiceFactory> &mediaKeysCapabilitiesModuleFactory,
48 : const std::shared_ptr<IWebAudioPlayerModuleServiceFactory> &webAudioPlayerModuleFactory,
49 : const std::shared_ptr<IControlModuleServiceFactory> &controlModuleFactory, service::IPlaybackService &playbackService,
50 9 : service::ICdmService &cdmService, service::IControlService &controlService)
51 9 : : m_isRunning{false},
52 9 : m_mediaPipelineModule{mediaPipelineModuleFactory->create(playbackService.getMediaPipelineService())},
53 9 : m_mediaPipelineCapabilitiesModule{
54 9 : mediaPipelineCapabilitiesModuleFactory->create(playbackService.getMediaPipelineService())},
55 9 : m_mediaKeysModule{mediaKeysModuleFactory->create(cdmService)},
56 9 : m_mediaKeysCapabilitiesModule{mediaKeysCapabilitiesModuleFactory->create(cdmService)},
57 9 : m_webAudioPlayerModule{webAudioPlayerModuleFactory->create(playbackService.getWebAudioPlayerService())},
58 18 : m_controlModule{controlModuleFactory->create(playbackService, controlService)}
59 : {
60 9 : m_ipcServer = ipcFactory->create();
61 : }
62 :
63 18 : SessionManagementServer::~SessionManagementServer()
64 : {
65 9 : stop();
66 9 : if (m_ipcServerThread.joinable())
67 : {
68 1 : m_ipcServerThread.join();
69 : }
70 18 : }
71 :
72 0 : size_t SessionManagementServer::getBufferSizeForPasswordStructureCalls() const
73 : {
74 : // Can return -1 on error
75 0 : return sysconf(_SC_GETPW_R_SIZE_MAX);
76 : }
77 :
78 6 : bool SessionManagementServer::initialize(const std::string &socketName, unsigned int socketPermissions,
79 : const std::string &socketOwner, const std::string &socketGroup)
80 : {
81 6 : RIALTO_SERVER_LOG_INFO("Initializing Session Management Server. Socket name: '%s'", socketName.c_str());
82 6 : if (!m_ipcServer)
83 : {
84 0 : RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - Ipc server instance is NULL");
85 0 : return false;
86 : }
87 :
88 : // add a socket for clients and associate with a streamer object
89 18 : if (!m_ipcServer->addSocket(socketName,
90 12 : std::bind(&SessionManagementServer::onClientConnected, this, std::placeholders::_1),
91 12 : std::bind(&SessionManagementServer::onClientDisconnected, this, std::placeholders::_1)))
92 : {
93 1 : RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - can't add socket '%s' to the ipc "
94 : "server",
95 : socketName.c_str());
96 1 : return false;
97 : }
98 :
99 5 : common::setFilePermissions(socketName, socketPermissions);
100 5 : common::setFileOwnership(socketName, socketOwner, socketGroup);
101 :
102 5 : return true;
103 : }
104 :
105 2 : bool SessionManagementServer::initialize(int32_t socketFd)
106 : {
107 2 : RIALTO_SERVER_LOG_INFO("Initializing Session Management Server. Socket fd: %d", socketFd);
108 2 : if (!m_ipcServer)
109 : {
110 0 : RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - Ipc server instance is NULL");
111 0 : return false;
112 : }
113 :
114 : // add a socket for clients and associate with a streamer object
115 6 : if (!m_ipcServer->addSocket(socketFd,
116 4 : std::bind(&SessionManagementServer::onClientConnected, this, std::placeholders::_1),
117 4 : std::bind(&SessionManagementServer::onClientDisconnected, this, std::placeholders::_1)))
118 : {
119 1 : RIALTO_SERVER_LOG_ERROR("Failed to initialize SessionManagementServer - can't add socket fd %d to the ipc "
120 : "server",
121 : socketFd);
122 1 : return false;
123 : }
124 1 : return true;
125 : }
126 :
127 1 : void SessionManagementServer::start()
128 : {
129 1 : if (m_isRunning.load())
130 : {
131 0 : RIALTO_SERVER_LOG_DEBUG("Server is already in running state");
132 0 : return;
133 : }
134 1 : RIALTO_SERVER_LOG_DEBUG("Starting Session Management Server event loop");
135 1 : m_isRunning.store(true);
136 1 : m_ipcServerThread = std::thread(
137 2 : [this]()
138 : {
139 1 : constexpr int kPollInterval{100};
140 1 : while (m_ipcServer->process() && m_isRunning.load())
141 : {
142 0 : m_ipcServer->wait(kPollInterval);
143 : }
144 1 : RIALTO_SERVER_LOG_MIL("Session Management Server event loop finished.");
145 1 : });
146 : }
147 :
148 9 : void SessionManagementServer::stop()
149 : {
150 9 : m_isRunning.store(false);
151 : }
152 :
153 1 : void SessionManagementServer::setLogLevels(RIALTO_DEBUG_LEVEL defaultLogLevels, RIALTO_DEBUG_LEVEL clientLogLevels,
154 : RIALTO_DEBUG_LEVEL ipcLogLevels, RIALTO_DEBUG_LEVEL commonLogLevels)
155 : {
156 1 : m_setLogLevelsService.setLogLevels(defaultLogLevels, clientLogLevels, ipcLogLevels, commonLogLevels);
157 : }
158 :
159 2 : void SessionManagementServer::onClientConnected(const std::shared_ptr<::firebolt::rialto::ipc::IClient> &client)
160 : {
161 2 : m_controlModule->clientConnected(client);
162 2 : m_mediaPipelineModule->clientConnected(client);
163 2 : m_mediaPipelineCapabilitiesModule->clientConnected(client);
164 2 : m_mediaKeysModule->clientConnected(client);
165 2 : m_mediaKeysCapabilitiesModule->clientConnected(client);
166 2 : m_webAudioPlayerModule->clientConnected(client);
167 2 : m_setLogLevelsService.clientConnected(client);
168 : }
169 :
170 1 : void SessionManagementServer::onClientDisconnected(const std::shared_ptr<::firebolt::rialto::ipc::IClient> &client)
171 : {
172 1 : m_setLogLevelsService.clientDisconnected(client);
173 1 : m_mediaKeysCapabilitiesModule->clientDisconnected(client);
174 1 : m_mediaKeysModule->clientDisconnected(client);
175 1 : m_mediaPipelineCapabilitiesModule->clientDisconnected(client);
176 1 : m_mediaPipelineModule->clientDisconnected(client);
177 1 : m_webAudioPlayerModule->clientDisconnected(client);
178 1 : m_controlModule->clientDisconnected(client);
179 : }
180 : } // namespace firebolt::rialto::server::ipc
|