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 "ServerManagerModuleService.h"
21 : #include "AckSender.h"
22 : #include "CapabilityConverters.h"
23 : #include "ISessionServerManager.h"
24 : #include "RialtoServerLogging.h"
25 : #include <AudioDecoderCapabilities.h>
26 : #include <IIpcController.h>
27 : #include <VideoDecoderCapabilities.h>
28 : #include <optional>
29 :
30 : using firebolt::rialto::ipc::common::deserialiseAudioCapabilities;
31 : using firebolt::rialto::ipc::common::deserialiseVideoCapabilities;
32 :
33 : namespace
34 : {
35 14 : firebolt::rialto::common::SessionServerState convertSessionServerState(const rialto::SessionServerState &state)
36 : {
37 14 : switch (state)
38 : {
39 1 : case rialto::SessionServerState::UNINITIALIZED:
40 1 : return firebolt::rialto::common::SessionServerState::UNINITIALIZED;
41 1 : case rialto::SessionServerState::INACTIVE:
42 1 : return firebolt::rialto::common::SessionServerState::INACTIVE;
43 10 : case rialto::SessionServerState::ACTIVE:
44 10 : return firebolt::rialto::common::SessionServerState::ACTIVE;
45 1 : case rialto::SessionServerState::NOT_RUNNING:
46 1 : return firebolt::rialto::common::SessionServerState::NOT_RUNNING;
47 1 : case rialto::SessionServerState::ERROR:
48 1 : return firebolt::rialto::common::SessionServerState::ERROR;
49 0 : case rialto::SessionServerState::SUSPENDED:
50 0 : return firebolt::rialto::common::SessionServerState::SUSPENDED;
51 : }
52 0 : return firebolt::rialto::common::SessionServerState::ERROR;
53 : }
54 : } // namespace
55 :
56 : namespace firebolt::rialto::server::ipc
57 : {
58 18 : std::shared_ptr<IServerManagerModuleServiceFactory> IServerManagerModuleServiceFactory::createFactory()
59 : {
60 18 : std::shared_ptr<IServerManagerModuleServiceFactory> factory;
61 :
62 : try
63 : {
64 18 : factory = std::make_shared<ServerManagerModuleServiceFactory>();
65 : }
66 0 : catch (const std::exception &e)
67 : {
68 0 : RIALTO_SERVER_LOG_ERROR("Failed to create the server maanger module service factory, reason: %s", e.what());
69 : }
70 :
71 18 : return factory;
72 : }
73 :
74 : std::shared_ptr<::rialto::ServerManagerModule>
75 18 : ServerManagerModuleServiceFactory::create(service::ISessionServerManager &sessionServerManager) const
76 : {
77 18 : std::shared_ptr<::rialto::ServerManagerModule> serverManagerModule;
78 : try
79 : {
80 18 : serverManagerModule = std::make_shared<ServerManagerModuleService>(sessionServerManager);
81 : }
82 0 : catch (const std::exception &e)
83 : {
84 0 : RIALTO_SERVER_LOG_ERROR("Failed to create the server manager module service, reason: %s", e.what());
85 : }
86 :
87 18 : return serverManagerModule;
88 : }
89 :
90 18 : ServerManagerModuleService::ServerManagerModuleService(service::ISessionServerManager &sessionServerManager)
91 18 : : m_sessionServerManager{sessionServerManager}
92 : {
93 : }
94 :
95 : ServerManagerModuleService::~ServerManagerModuleService() {}
96 :
97 8 : void ServerManagerModuleService::setConfiguration(::google::protobuf::RpcController *controller,
98 : const ::rialto::SetConfigurationRequest *request,
99 : ::rialto::SetConfigurationResponse *response,
100 : ::google::protobuf::Closure *done)
101 : {
102 8 : RIALTO_SERVER_LOG_DEBUG("SetConfiguration received from ServerManager");
103 8 : common::MaxResourceCapabilitites maxResource{request->resources().maxplaybacks(),
104 8 : request->resources().maxwebaudioplayers()};
105 8 : const auto kClientDisplayName = request->has_clientdisplayname() ? request->clientdisplayname() : "";
106 :
107 : // Deserialise typed capability fields into C++ structs (optional — absent fields → std::nullopt)
108 8 : std::optional<firebolt::rialto::common::AudioDecoderCapabilities> audioCaps;
109 8 : std::optional<firebolt::rialto::common::VideoDecoderCapabilities> videoCaps;
110 8 : if (request->has_audiocapabilities())
111 : {
112 2 : RIALTO_SERVER_LOG_DEBUG("ServerManagerModuleService: audio capabilities received in SetConfiguration");
113 2 : audioCaps = deserialiseAudioCapabilities(request->audiocapabilities());
114 : }
115 8 : if (request->has_videocapabilities())
116 : {
117 2 : RIALTO_SERVER_LOG_DEBUG("ServerManagerModuleService: video capabilities received in SetConfiguration");
118 2 : videoCaps = deserialiseVideoCapabilities(request->videocapabilities());
119 : }
120 8 : if (audioCaps.has_value() || videoCaps.has_value())
121 : {
122 2 : RIALTO_SERVER_LOG_INFO(
123 : "ServerManagerModuleService: capabilities deserialised and forwarded to configureServices");
124 : }
125 : else
126 : {
127 6 : RIALTO_SERVER_LOG_INFO(
128 : "ServerManagerModuleService: no capability fields - session server will use GStreamer query fallback");
129 : }
130 :
131 8 : bool success{true};
132 8 : if (request->has_sessionmanagementsocketfd())
133 : {
134 4 : m_sessionServerManager.configureIpc(request->sessionmanagementsocketfd());
135 : }
136 : else
137 : {
138 4 : m_sessionServerManager.configureIpc(request->sessionmanagementsocketname(), request->socketpermissions(),
139 : request->socketowner(), request->socketgroup());
140 : }
141 :
142 : // Pass preloaded capabilities to MediaPipelineService via setPreloadedCapabilities()
143 : // This allows Path 0 (preloaded YAML) to be used before falling back to GStreamer Path B
144 8 : m_sessionServerManager.setPreloadedCapabilities(audioCaps, videoCaps);
145 :
146 8 : success &= m_sessionServerManager.configureServices(convertSessionServerState(request->initialsessionserverstate()),
147 : maxResource, kClientDisplayName, request->appname());
148 8 : m_sessionServerManager.setLogLevels(static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().defaultloglevels()),
149 8 : static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().clientloglevels()),
150 8 : static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().sessionserverloglevels()),
151 8 : static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().ipcloglevels()),
152 8 : static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().servermanagerloglevels()),
153 8 : static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().commonloglevels()));
154 8 : if (!success)
155 : {
156 2 : RIALTO_SERVER_LOG_ERROR("SetConfiguration operation failed");
157 6 : controller->SetFailed("SetConfiguration failed");
158 : }
159 8 : done->Run();
160 : }
161 :
162 6 : void ServerManagerModuleService::setState(::google::protobuf::RpcController *controller,
163 : const ::rialto::SetStateRequest *request,
164 : ::rialto::SetStateResponse *response, ::google::protobuf::Closure *done)
165 : {
166 6 : RIALTO_SERVER_LOG_DEBUG("SetState received from ServerManager");
167 6 : bool success = m_sessionServerManager.setState(convertSessionServerState(request->sessionserverstate()));
168 6 : if (!success)
169 : {
170 1 : RIALTO_SERVER_LOG_ERROR("SetState operation failed");
171 3 : controller->SetFailed("SetState failed");
172 : }
173 6 : done->Run();
174 : }
175 :
176 1 : void ServerManagerModuleService::setLogLevels(::google::protobuf::RpcController *controller,
177 : const ::rialto::SetLogLevelsRequest *request,
178 : ::rialto::SetLogLevelsResponse *response, ::google::protobuf::Closure *done)
179 : {
180 1 : RIALTO_SERVER_LOG_DEBUG("setLogLevels received from ServerManager");
181 1 : m_sessionServerManager.setLogLevels(static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().defaultloglevels()),
182 1 : static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().clientloglevels()),
183 1 : static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().sessionserverloglevels()),
184 1 : static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().ipcloglevels()),
185 1 : static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().servermanagerloglevels()),
186 1 : static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().commonloglevels()));
187 1 : done->Run();
188 : }
189 :
190 3 : void ServerManagerModuleService::ping(::google::protobuf::RpcController *controller, const ::rialto::PingRequest *request,
191 : ::rialto::PingResponse *response, ::google::protobuf::Closure *done)
192 : {
193 3 : RIALTO_SERVER_LOG_DEBUG("Ping received from ServerManager");
194 3 : auto ipcController = dynamic_cast<firebolt::rialto::ipc::IController *>(controller);
195 3 : if (!ipcController)
196 : {
197 1 : RIALTO_SERVER_LOG_ERROR("ipc library provided incompatible controller object");
198 2 : controller->SetFailed("ipc library provided incompatible controller object");
199 1 : done->Run();
200 1 : return;
201 : }
202 2 : bool success = m_sessionServerManager.ping(request->id(), std::make_shared<AckSender>(ipcController->getClient()));
203 2 : if (!success)
204 : {
205 1 : RIALTO_SERVER_LOG_ERROR("Ping failed");
206 3 : controller->SetFailed("Ping failed");
207 : }
208 2 : done->Run();
209 : }
210 : } // namespace firebolt::rialto::server::ipc
|