LCOV - code coverage report
Current view: top level - media/server/main/source - MediaKeysServerInternal.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.4 % 365 352
Test Date: 2025-04-04 09:14:39 Functions: 100.0 % 76 76

            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 <stdexcept>
      21              : 
      22              : #include "MediaKeysServerInternal.h"
      23              : #include "RialtoServerLogging.h"
      24              : 
      25              : namespace firebolt::rialto
      26              : {
      27            1 : const char *mediaKeyErrorStatusToString(const MediaKeyErrorStatus &status)
      28              : {
      29            1 :     switch (status)
      30              :     {
      31            0 :     case firebolt::rialto::MediaKeyErrorStatus::OK:
      32            0 :         return "OK";
      33            0 :     case firebolt::rialto::MediaKeyErrorStatus::BAD_SESSION_ID:
      34            0 :         return "BAD_SESSION_ID";
      35            1 :     case firebolt::rialto::MediaKeyErrorStatus::INTERFACE_NOT_IMPLEMENTED:
      36            1 :         return "INTERFACE_NOT_IMPLEMENTED";
      37            0 :     case firebolt::rialto::MediaKeyErrorStatus::BUFFER_TOO_SMALL:
      38            0 :         return "BUFFER_TOO_SMALL";
      39            0 :     case firebolt::rialto::MediaKeyErrorStatus::NOT_SUPPORTED:
      40            0 :         return "NOT_SUPPORTED";
      41            0 :     default:
      42            0 :         return "FAIL";
      43              :     }
      44              : }
      45              : 
      46            1 : std::shared_ptr<IMediaKeysFactory> IMediaKeysFactory::createFactory()
      47              : {
      48            1 :     return server::IMediaKeysServerInternalFactory::createFactory();
      49              : }
      50              : } // namespace firebolt::rialto
      51              : 
      52              : namespace firebolt::rialto::server
      53              : {
      54           68 : int32_t generateSessionId()
      55              : {
      56              :     static int32_t keySessionId{0};
      57           68 :     return keySessionId++;
      58              : }
      59              : 
      60            2 : std::shared_ptr<IMediaKeysServerInternalFactory> IMediaKeysServerInternalFactory::createFactory()
      61              : {
      62            2 :     std::shared_ptr<IMediaKeysServerInternalFactory> factory;
      63              : 
      64              :     try
      65              :     {
      66            2 :         factory = std::make_shared<MediaKeysServerInternalFactory>();
      67              :     }
      68            0 :     catch (const std::exception &e)
      69              :     {
      70            0 :         RIALTO_SERVER_LOG_ERROR("Failed to create the media keys factory, reason: %s", e.what());
      71              :     }
      72              : 
      73            2 :     return factory;
      74              : }
      75              : 
      76            1 : std::unique_ptr<IMediaKeys> MediaKeysServerInternalFactory::createMediaKeys(const std::string &keySystem) const
      77              : {
      78            1 :     RIALTO_SERVER_LOG_ERROR("This function can't be used by rialto server. Please use createMediaKeysServerInternal");
      79            1 :     return nullptr;
      80              : }
      81              : 
      82              : std::unique_ptr<IMediaKeysServerInternal>
      83            1 : MediaKeysServerInternalFactory::createMediaKeysServerInternal(const std::string &keySystem) const
      84              : {
      85            1 :     std::unique_ptr<IMediaKeysServerInternal> mediaKeys;
      86              :     try
      87              :     {
      88            2 :         mediaKeys = std::make_unique<server::MediaKeysServerInternal>(keySystem,
      89            3 :                                                                       server::IMainThreadFactory::createFactory(),
      90            3 :                                                                       wrappers::IOcdmSystemFactory::createFactory(),
      91            3 :                                                                       server::IMediaKeySessionFactory::createFactory());
      92              :     }
      93            1 :     catch (const std::exception &e)
      94              :     {
      95            1 :         RIALTO_SERVER_LOG_ERROR("Failed to create the media keys, reason: %s", e.what());
      96              :     }
      97              : 
      98            1 :     return mediaKeys;
      99              : }
     100              : }; // namespace firebolt::rialto::server
     101              : 
     102              : namespace firebolt::rialto::server
     103              : {
     104           73 : MediaKeysServerInternal::MediaKeysServerInternal(
     105              :     const std::string &keySystem, const std::shared_ptr<IMainThreadFactory> &mainThreadFactory,
     106              :     std::shared_ptr<firebolt::rialto::wrappers::IOcdmSystemFactory> ocdmSystemFactory,
     107           73 :     std::shared_ptr<IMediaKeySessionFactory> mediaKeySessionFactory)
     108           73 :     : m_mediaKeySessionFactory(mediaKeySessionFactory), m_keySystem(keySystem)
     109              : {
     110           73 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     111              : 
     112           73 :     m_mainThread = mainThreadFactory->getMainThread();
     113           73 :     if (!m_mainThread)
     114              :     {
     115            1 :         throw std::runtime_error("Failed to get the main thread");
     116              :     }
     117           72 :     m_mainThreadClientId = m_mainThread->registerClient();
     118              : 
     119           72 :     if (!ocdmSystemFactory)
     120              :     {
     121            1 :         throw std::runtime_error("No ocdmSystemFactory");
     122              :     }
     123              : 
     124           71 :     bool result = false;
     125           71 :     auto task = [&]()
     126              :     {
     127           71 :         m_ocdmSystem = ocdmSystemFactory->createOcdmSystem(keySystem);
     128           71 :         if (!m_ocdmSystem)
     129              :         {
     130            1 :             RIALTO_SERVER_LOG_ERROR("Ocdm system could not be created");
     131              :         }
     132              :         else
     133              :         {
     134           70 :             result = true;
     135              :         }
     136           71 :     };
     137              : 
     138           71 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     139           71 :     if (!result)
     140              :     {
     141            1 :         throw std::runtime_error("MediaKeys construction failed");
     142              :     }
     143           88 : }
     144              : 
     145          210 : MediaKeysServerInternal::~MediaKeysServerInternal()
     146              : {
     147           70 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     148              : 
     149           70 :     auto task = [&]()
     150              :     {
     151           70 :         m_ocdmSystem.reset();
     152              : 
     153           70 :         m_mainThread->unregisterClient(m_mainThreadClientId);
     154          140 :     };
     155              : 
     156           70 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     157          140 : }
     158              : 
     159            3 : MediaKeyErrorStatus MediaKeysServerInternal::selectKeyId(int32_t keySessionId, const std::vector<uint8_t> &keyId)
     160              : {
     161            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     162              : 
     163              :     MediaKeyErrorStatus status;
     164            3 :     auto task = [&]() { status = selectKeyIdInternal(keySessionId, keyId); };
     165              : 
     166            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     167            3 :     return status;
     168              : }
     169              : 
     170            3 : MediaKeyErrorStatus MediaKeysServerInternal::selectKeyIdInternal(int32_t keySessionId, const std::vector<uint8_t> &keyId)
     171              : {
     172            3 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     173            3 :     if (sessionIter == m_mediaKeySessions.end())
     174              :     {
     175            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     176            1 :         return MediaKeyErrorStatus::BAD_SESSION_ID;
     177              :     }
     178              : 
     179            2 :     MediaKeyErrorStatus status = sessionIter->second.mediaKeySession->selectKeyId(keyId);
     180            2 :     if (MediaKeyErrorStatus::OK != status)
     181              :     {
     182            1 :         RIALTO_SERVER_LOG_ERROR("Failed to select key id");
     183            1 :         return status;
     184              :     }
     185              : 
     186            1 :     return status;
     187              : }
     188              : 
     189            3 : bool MediaKeysServerInternal::containsKey(int32_t keySessionId, const std::vector<uint8_t> &keyId)
     190              : {
     191            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     192              : 
     193            3 :     bool result{false};
     194            3 :     auto task = [&]() { result = containsKeyInternal(keySessionId, keyId); };
     195              : 
     196            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     197            3 :     return result;
     198              : }
     199              : 
     200            3 : bool MediaKeysServerInternal::containsKeyInternal(int32_t keySessionId, const std::vector<uint8_t> &keyId)
     201              : {
     202            3 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     203            3 :     if (sessionIter == m_mediaKeySessions.end())
     204              :     {
     205            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     206            1 :         return false;
     207              :     }
     208              : 
     209            2 :     return sessionIter->second.mediaKeySession->containsKey(keyId);
     210              : }
     211              : 
     212           68 : MediaKeyErrorStatus MediaKeysServerInternal::createKeySession(KeySessionType sessionType,
     213              :                                                               std::weak_ptr<IMediaKeysClient> client, bool isLDL,
     214              :                                                               int32_t &keySessionId)
     215              : {
     216           68 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     217              : 
     218              :     MediaKeyErrorStatus status;
     219           68 :     auto task = [&]() { status = createKeySessionInternal(sessionType, client, isLDL, keySessionId); };
     220              : 
     221           68 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     222           68 :     return status;
     223              : }
     224              : 
     225           68 : MediaKeyErrorStatus MediaKeysServerInternal::createKeySessionInternal(KeySessionType sessionType,
     226              :                                                                       std::weak_ptr<IMediaKeysClient> client,
     227              :                                                                       bool isLDL, int32_t &keySessionId)
     228              : {
     229           68 :     int32_t keySessionIdTemp = generateSessionId();
     230              :     std::unique_ptr<IMediaKeySession> mediaKeySession =
     231          136 :         m_mediaKeySessionFactory->createMediaKeySession(m_keySystem, keySessionIdTemp, *m_ocdmSystem, sessionType,
     232          136 :                                                         client, isLDL);
     233           68 :     if (!mediaKeySession)
     234              :     {
     235            1 :         RIALTO_SERVER_LOG_ERROR("Failed to create a new media key session");
     236            1 :         return MediaKeyErrorStatus::FAIL;
     237              :     }
     238           67 :     keySessionId = keySessionIdTemp;
     239           67 :     m_mediaKeySessions.emplace(std::make_pair(keySessionId, MediaKeySessionUsage{std::move(mediaKeySession)}));
     240              : 
     241           67 :     return MediaKeyErrorStatus::OK;
     242           68 : }
     243              : 
     244            3 : MediaKeyErrorStatus MediaKeysServerInternal::generateRequest(int32_t keySessionId, InitDataType initDataType,
     245              :                                                              const std::vector<uint8_t> &initData)
     246              : {
     247            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     248              : 
     249              :     MediaKeyErrorStatus status;
     250            3 :     auto task = [&]() { status = generateRequestInternal(keySessionId, initDataType, initData); };
     251              : 
     252            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     253            3 :     return status;
     254              : }
     255              : 
     256            3 : MediaKeyErrorStatus MediaKeysServerInternal::generateRequestInternal(int32_t keySessionId, InitDataType initDataType,
     257              :                                                                      const std::vector<uint8_t> &initData)
     258              : {
     259            3 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     260            3 :     if (sessionIter == m_mediaKeySessions.end())
     261              :     {
     262            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     263            1 :         return MediaKeyErrorStatus::BAD_SESSION_ID;
     264              :     }
     265              : 
     266            2 :     MediaKeyErrorStatus status = sessionIter->second.mediaKeySession->generateRequest(initDataType, initData);
     267            2 :     if (MediaKeyErrorStatus::OK != status)
     268              :     {
     269            1 :         RIALTO_SERVER_LOG_ERROR("Failed to generate request for the key session %d", keySessionId);
     270            1 :         return status;
     271              :     }
     272            1 :     return status;
     273              : }
     274              : 
     275            3 : MediaKeyErrorStatus MediaKeysServerInternal::loadSession(int32_t keySessionId)
     276              : {
     277            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     278              : 
     279              :     MediaKeyErrorStatus status;
     280            3 :     auto task = [&]() { status = loadSessionInternal(keySessionId); };
     281              : 
     282            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     283            3 :     return status;
     284              : }
     285              : 
     286            3 : MediaKeyErrorStatus MediaKeysServerInternal::loadSessionInternal(int32_t keySessionId)
     287              : {
     288            3 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     289            3 :     if (sessionIter == m_mediaKeySessions.end())
     290              :     {
     291            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     292            1 :         return MediaKeyErrorStatus::BAD_SESSION_ID;
     293              :     }
     294              : 
     295            2 :     MediaKeyErrorStatus status = sessionIter->second.mediaKeySession->loadSession();
     296            2 :     if (MediaKeyErrorStatus::OK != status)
     297              :     {
     298            1 :         RIALTO_SERVER_LOG_ERROR("Failed to load the session %d", keySessionId);
     299            1 :         return status;
     300              :     }
     301            1 :     return status;
     302              : }
     303              : 
     304            3 : MediaKeyErrorStatus MediaKeysServerInternal::updateSession(int32_t keySessionId, const std::vector<uint8_t> &responseData)
     305              : {
     306            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     307              : 
     308              :     MediaKeyErrorStatus status;
     309            3 :     auto task = [&]() { status = updateSessionInternal(keySessionId, responseData); };
     310              : 
     311            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     312            3 :     return status;
     313              : }
     314              : 
     315            3 : MediaKeyErrorStatus MediaKeysServerInternal::updateSessionInternal(int32_t keySessionId,
     316              :                                                                    const std::vector<uint8_t> &responseData)
     317              : {
     318            3 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     319            3 :     if (sessionIter == m_mediaKeySessions.end())
     320              :     {
     321            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     322            1 :         return MediaKeyErrorStatus::BAD_SESSION_ID;
     323              :     }
     324              : 
     325            2 :     MediaKeyErrorStatus status = sessionIter->second.mediaKeySession->updateSession(responseData);
     326            2 :     if (MediaKeyErrorStatus::OK != status)
     327              :     {
     328            1 :         RIALTO_SERVER_LOG_ERROR("Failed to update the session %d", keySessionId);
     329            1 :         return status;
     330              :     }
     331            1 :     return status;
     332              : }
     333              : 
     334            3 : MediaKeyErrorStatus MediaKeysServerInternal::setDrmHeader(int32_t keySessionId, const std::vector<uint8_t> &requestData)
     335              : {
     336            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     337              : 
     338              :     MediaKeyErrorStatus status;
     339            3 :     auto task = [&]() { status = setDrmHeaderInternal(keySessionId, requestData); };
     340              : 
     341            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     342            3 :     return status;
     343              : }
     344              : 
     345            3 : MediaKeyErrorStatus MediaKeysServerInternal::setDrmHeaderInternal(int32_t keySessionId,
     346              :                                                                   const std::vector<uint8_t> &requestData)
     347              : {
     348            3 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     349            3 :     if (sessionIter == m_mediaKeySessions.end())
     350              :     {
     351            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     352            1 :         return MediaKeyErrorStatus::BAD_SESSION_ID;
     353              :     }
     354              : 
     355            2 :     MediaKeyErrorStatus status = sessionIter->second.mediaKeySession->setDrmHeader(requestData);
     356            2 :     if (MediaKeyErrorStatus::OK != status)
     357              :     {
     358            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set drm header");
     359            1 :         return status;
     360              :     }
     361              : 
     362            1 :     return status;
     363              : }
     364              : 
     365            8 : MediaKeyErrorStatus MediaKeysServerInternal::closeKeySession(int32_t keySessionId)
     366              : {
     367            8 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     368              : 
     369              :     MediaKeyErrorStatus status;
     370            8 :     auto task = [&]() { status = closeKeySessionInternal(keySessionId); };
     371              : 
     372            8 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     373            8 :     return status;
     374              : }
     375              : 
     376            8 : MediaKeyErrorStatus MediaKeysServerInternal::closeKeySessionInternal(int32_t keySessionId)
     377              : {
     378            8 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     379            8 :     if (sessionIter == m_mediaKeySessions.end())
     380              :     {
     381            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     382            1 :         return MediaKeyErrorStatus::BAD_SESSION_ID;
     383              :     }
     384              : 
     385            7 :     if (sessionIter->second.bufCounter == 0)
     386              :     {
     387            3 :         MediaKeyErrorStatus status = sessionIter->second.mediaKeySession->closeKeySession();
     388            3 :         if (MediaKeyErrorStatus::OK != status)
     389              :         {
     390            1 :             RIALTO_SERVER_LOG_ERROR("Failed to close the key session %d", keySessionId);
     391            1 :             return status;
     392              :         }
     393            2 :         return status;
     394              :     }
     395              : 
     396            4 :     RIALTO_SERVER_LOG_INFO("Deferring closing of key session %d", keySessionId);
     397            4 :     sessionIter->second.shouldBeClosed = true;
     398            4 :     return MediaKeyErrorStatus::OK;
     399              : }
     400              : 
     401           11 : MediaKeyErrorStatus MediaKeysServerInternal::removeKeySession(int32_t keySessionId)
     402              : {
     403           11 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     404              : 
     405              :     MediaKeyErrorStatus status;
     406           11 :     auto task = [&]() { status = removeKeySessionInternal(keySessionId); };
     407              : 
     408           11 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     409           11 :     return status;
     410              : }
     411              : 
     412           11 : MediaKeyErrorStatus MediaKeysServerInternal::removeKeySessionInternal(int32_t keySessionId)
     413              : {
     414           11 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     415           11 :     if (sessionIter == m_mediaKeySessions.end())
     416              :     {
     417            4 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     418            4 :         return MediaKeyErrorStatus::BAD_SESSION_ID;
     419              :     }
     420              : 
     421            7 :     MediaKeyErrorStatus status = sessionIter->second.mediaKeySession->removeKeySession();
     422            7 :     if (MediaKeyErrorStatus::OK != status)
     423              :     {
     424            1 :         RIALTO_SERVER_LOG_ERROR("Failed to remove the key session %d", keySessionId);
     425            1 :         return status;
     426              :     }
     427            6 :     return status;
     428              : }
     429              : 
     430            2 : MediaKeyErrorStatus MediaKeysServerInternal::deleteDrmStore()
     431              : {
     432            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     433              : 
     434              :     MediaKeyErrorStatus status;
     435            2 :     auto task = [&]() { status = m_ocdmSystem->deleteSecureStore(); };
     436              : 
     437            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     438            2 :     return status;
     439              : }
     440              : 
     441            2 : MediaKeyErrorStatus MediaKeysServerInternal::deleteKeyStore()
     442              : {
     443            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     444              : 
     445              :     MediaKeyErrorStatus status;
     446            2 :     auto task = [&]() { status = m_ocdmSystem->deleteKeyStore(); };
     447              : 
     448            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     449            2 :     return status;
     450              : }
     451              : 
     452            2 : MediaKeyErrorStatus MediaKeysServerInternal::getDrmStoreHash(std::vector<unsigned char> &drmStoreHash)
     453              : {
     454            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     455            2 :     constexpr size_t kHashSize{256};
     456            2 :     drmStoreHash.resize(kHashSize);
     457              :     MediaKeyErrorStatus status;
     458            2 :     auto task = [&]() { status = m_ocdmSystem->getSecureStoreHash(&drmStoreHash[0], kHashSize); };
     459            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     460            2 :     return status;
     461              : }
     462              : 
     463            2 : MediaKeyErrorStatus MediaKeysServerInternal::getKeyStoreHash(std::vector<unsigned char> &keyStoreHash)
     464              : {
     465            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     466            2 :     constexpr size_t kHashSize{256};
     467            2 :     keyStoreHash.resize(kHashSize);
     468              :     MediaKeyErrorStatus status;
     469            2 :     auto task = [&]() { status = m_ocdmSystem->getKeyStoreHash(&keyStoreHash[0], kHashSize); };
     470            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     471            2 :     return status;
     472              : }
     473              : 
     474            2 : MediaKeyErrorStatus MediaKeysServerInternal::getLdlSessionsLimit(uint32_t &ldlLimit)
     475              : {
     476            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     477              : 
     478              :     MediaKeyErrorStatus status;
     479            2 :     auto task = [&]() { status = m_ocdmSystem->getLdlSessionsLimit(&ldlLimit); };
     480              : 
     481            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     482            2 :     return status;
     483              : }
     484              : 
     485            3 : MediaKeyErrorStatus MediaKeysServerInternal::getLastDrmError(int32_t keySessionId, uint32_t &errorCode)
     486              : {
     487            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     488              : 
     489              :     MediaKeyErrorStatus status;
     490            3 :     auto task = [&]() { status = getLastDrmErrorInternal(keySessionId, errorCode); };
     491              : 
     492            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     493            3 :     return status;
     494              : }
     495              : 
     496            3 : MediaKeyErrorStatus MediaKeysServerInternal::getLastDrmErrorInternal(int32_t keySessionId, uint32_t &errorCode)
     497              : {
     498            3 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     499            3 :     if (sessionIter == m_mediaKeySessions.end())
     500              :     {
     501            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     502            1 :         return MediaKeyErrorStatus::BAD_SESSION_ID;
     503              :     }
     504              : 
     505            2 :     MediaKeyErrorStatus status = sessionIter->second.mediaKeySession->getLastDrmError(errorCode);
     506            2 :     if (MediaKeyErrorStatus::OK != status)
     507              :     {
     508            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get last drm error");
     509              :     }
     510              : 
     511            2 :     return status;
     512              : }
     513              : 
     514            2 : MediaKeyErrorStatus MediaKeysServerInternal::getDrmTime(uint64_t &drmTime)
     515              : {
     516              :     MediaKeyErrorStatus status;
     517            2 :     auto task = [&]() { status = m_ocdmSystem->getDrmTime(&drmTime); };
     518              : 
     519            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     520            2 :     return status;
     521              : }
     522              : 
     523            3 : MediaKeyErrorStatus MediaKeysServerInternal::getCdmKeySessionId(int32_t keySessionId, std::string &cdmKeySessionId)
     524              : {
     525            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     526              : 
     527              :     MediaKeyErrorStatus status;
     528            3 :     auto task = [&]() { status = getCdmKeySessionIdInternal(keySessionId, cdmKeySessionId); };
     529              : 
     530            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     531            3 :     return status;
     532              : }
     533              : 
     534            7 : MediaKeyErrorStatus MediaKeysServerInternal::releaseKeySession(int32_t keySessionId)
     535              : {
     536            7 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     537              : 
     538              :     MediaKeyErrorStatus status;
     539            7 :     auto task = [&]() { status = releaseKeySessionInternal(keySessionId); };
     540              : 
     541            7 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     542            7 :     return status;
     543              : }
     544              : 
     545            7 : MediaKeyErrorStatus MediaKeysServerInternal::releaseKeySessionInternal(int32_t keySessionId)
     546              : {
     547            7 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     548            7 :     if (sessionIter == m_mediaKeySessions.end())
     549              :     {
     550            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     551            1 :         return MediaKeyErrorStatus::BAD_SESSION_ID;
     552              :     }
     553              : 
     554            6 :     if (sessionIter->second.bufCounter == 0)
     555              :     {
     556            2 :         m_mediaKeySessions.erase(sessionIter);
     557            2 :         return MediaKeyErrorStatus::OK;
     558              :     }
     559              : 
     560            4 :     RIALTO_SERVER_LOG_INFO("Deferring releasing of key session %d", keySessionId);
     561            4 :     sessionIter->second.shouldBeReleased = true;
     562            4 :     return MediaKeyErrorStatus::OK;
     563              : }
     564              : 
     565            3 : MediaKeyErrorStatus MediaKeysServerInternal::getCdmKeySessionIdInternal(int32_t keySessionId, std::string &cdmKeySessionId)
     566              : {
     567            3 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     568            3 :     if (sessionIter == m_mediaKeySessions.end())
     569              :     {
     570            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     571            1 :         return MediaKeyErrorStatus::BAD_SESSION_ID;
     572              :     }
     573              : 
     574            2 :     MediaKeyErrorStatus status = sessionIter->second.mediaKeySession->getCdmKeySessionId(cdmKeySessionId);
     575            2 :     if (MediaKeyErrorStatus::OK != status)
     576              :     {
     577            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get cdm key session id");
     578            1 :         return status;
     579              :     }
     580              : 
     581            1 :     return status;
     582              : }
     583              : 
     584            3 : MediaKeyErrorStatus MediaKeysServerInternal::decrypt(int32_t keySessionId, GstBuffer *encrypted, GstCaps *caps)
     585              : {
     586            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     587              : 
     588              :     MediaKeyErrorStatus status;
     589            3 :     auto task = [&]() { status = decryptInternal(keySessionId, encrypted, caps); };
     590              : 
     591            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     592            3 :     return status;
     593              : }
     594              : 
     595            3 : MediaKeyErrorStatus MediaKeysServerInternal::decryptInternal(int32_t keySessionId, GstBuffer *encrypted, GstCaps *caps)
     596              : {
     597            3 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     598            3 :     if (sessionIter == m_mediaKeySessions.end())
     599              :     {
     600            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     601            1 :         return MediaKeyErrorStatus::BAD_SESSION_ID;
     602              :     }
     603              : 
     604            2 :     MediaKeyErrorStatus status = sessionIter->second.mediaKeySession->decrypt(encrypted, caps);
     605            2 :     if (MediaKeyErrorStatus::OK != status)
     606              :     {
     607            1 :         RIALTO_SERVER_LOG_ERROR("Failed to decrypt buffer.");
     608            1 :         return status;
     609              :     }
     610              : 
     611            1 :     return status;
     612              : }
     613              : 
     614            1 : bool MediaKeysServerInternal::hasSession(int32_t keySessionId) const
     615              : {
     616            1 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     617              : 
     618              :     bool result;
     619            1 :     auto task = [&]() { result = m_mediaKeySessions.find(keySessionId) != m_mediaKeySessions.end(); };
     620              : 
     621            1 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     622            1 :     return result;
     623              : }
     624              : 
     625            3 : bool MediaKeysServerInternal::isNetflixPlayreadyKeySystem(int32_t keySessionId) const
     626              : {
     627            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     628              :     bool result;
     629            3 :     auto task = [&]() { result = isNetflixPlayreadyKeySystemInternal(keySessionId); };
     630              : 
     631            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     632            3 :     return result;
     633              : }
     634              : 
     635            3 : bool MediaKeysServerInternal::isNetflixPlayreadyKeySystemInternal(int32_t keySessionId) const
     636              : {
     637            3 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     638            3 :     if (sessionIter == m_mediaKeySessions.end())
     639              :     {
     640            1 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     641            1 :         return false;
     642              :     }
     643            2 :     return sessionIter->second.mediaKeySession->isNetflixPlayreadyKeySystem();
     644              : }
     645              : 
     646           12 : void MediaKeysServerInternal::incrementSessionIdUsageCounter(int32_t keySessionId)
     647              : {
     648           12 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     649           12 :     auto task = [&]() { incrementSessionIdUsageCounterInternal(keySessionId); };
     650              : 
     651           12 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     652              : }
     653              : 
     654           12 : void MediaKeysServerInternal::incrementSessionIdUsageCounterInternal(int32_t keySessionId)
     655              : {
     656           12 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     657           12 :     if (sessionIter == m_mediaKeySessions.end())
     658              :     {
     659            2 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     660            2 :         return;
     661              :     }
     662              : 
     663           10 :     sessionIter->second.bufCounter++;
     664              : }
     665              : 
     666            8 : void MediaKeysServerInternal::decrementSessionIdUsageCounter(int32_t keySessionId)
     667              : {
     668            8 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     669            8 :     auto task = [&]() { decrementSessionIdUsageCounterInternal(keySessionId); };
     670              : 
     671            8 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     672              : }
     673              : 
     674            8 : void MediaKeysServerInternal::decrementSessionIdUsageCounterInternal(int32_t keySessionId)
     675              : {
     676            8 :     auto sessionIter = m_mediaKeySessions.find(keySessionId);
     677            8 :     if (sessionIter == m_mediaKeySessions.end())
     678              :     {
     679            2 :         RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
     680            2 :         return;
     681              :     }
     682              : 
     683            6 :     if (sessionIter->second.bufCounter > 0)
     684              :     {
     685            4 :         sessionIter->second.bufCounter--;
     686              :     }
     687              : 
     688            6 :     if (sessionIter->second.bufCounter == 0)
     689              :     {
     690            4 :         if (sessionIter->second.shouldBeClosed)
     691              :         {
     692            1 :             RIALTO_SERVER_LOG_INFO("Deferred closing of mksId %d", keySessionId);
     693            1 :             MediaKeyErrorStatus status = sessionIter->second.mediaKeySession->closeKeySession();
     694            1 :             if (MediaKeyErrorStatus::OK != status)
     695              :             {
     696            0 :                 RIALTO_SERVER_LOG_ERROR("Failed to close the key session %d", keySessionId);
     697              :             }
     698              :         }
     699            4 :         if (sessionIter->second.shouldBeReleased)
     700              :         {
     701            1 :             m_mediaKeySessions.erase(sessionIter);
     702              :         }
     703              :     }
     704              : }
     705              : 
     706            1 : void MediaKeysServerInternal::ping(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler)
     707              : {
     708            1 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     709            1 :     auto task = [&]() { heartbeatHandler.reset(); };
     710              : 
     711            1 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     712              : }
     713              : 
     714            4 : MediaKeyErrorStatus MediaKeysServerInternal::getMetricSystemData(std::vector<uint8_t> &buffer)
     715              : {
     716            4 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     717              : 
     718            4 :     uint32_t bufferLength{1024};
     719            4 :     const uint32_t kMaxBufferLength{65536};
     720              :     MediaKeyErrorStatus status;
     721            4 :     buffer.resize(bufferLength);
     722              : 
     723           11 :     for (int attempts = 0; bufferLength <= kMaxBufferLength; ++attempts)
     724              :     {
     725           11 :         auto task = [&]() { status = m_ocdmSystem->getMetricSystemData(bufferLength, buffer); };
     726           11 :         m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     727              : 
     728           11 :         if (status != MediaKeyErrorStatus::BUFFER_TOO_SMALL)
     729              :         {
     730            3 :             break;
     731              :         }
     732              : 
     733            8 :         if (bufferLength >= kMaxBufferLength)
     734              :         {
     735            1 :             RIALTO_SERVER_LOG_ERROR("Buffer size %u exceeds the maximum allowed size %u", bufferLength, kMaxBufferLength);
     736            1 :             return MediaKeyErrorStatus::BUFFER_TOO_SMALL;
     737              :         }
     738              : 
     739            7 :         RIALTO_SERVER_LOG_WARN("Buffer is too small, resizing from %u to %u", bufferLength, bufferLength * 2);
     740            7 :         bufferLength *= 2;
     741            7 :         buffer.resize(bufferLength);
     742              :     }
     743              : 
     744            3 :     if (status == MediaKeyErrorStatus::OK)
     745              :     {
     746              :         // If the buffer remains larger than bufferLength (due to a previous resize),
     747              :         // the client may have values in the extra space. So this resize would ensure the buffer is trimmed to the correct size.
     748            2 :         buffer.resize(bufferLength);
     749            2 :         RIALTO_SERVER_LOG_DEBUG("Successfully retrieved metric system data, final buffer length: %u", bufferLength);
     750              :     }
     751              :     else
     752              :     {
     753            1 :         RIALTO_SERVER_LOG_ERROR("Failed to retrieve metric system data, status: %s, last buffer length tried: %u",
     754              :                                 firebolt::rialto::mediaKeyErrorStatusToString(status), bufferLength);
     755              :     }
     756            3 :     return status;
     757              : }
     758              : 
     759              : }; // namespace firebolt::rialto::server
        

Generated by: LCOV version 2.0-1