Skip to content

RDKEMW-11877: Metrics Collection for Player Interface Public APIs - Phase1#66

Open
nejuma1 wants to merge 11 commits intofeature/RDKEMW-11881from
feature/RDKEMW-11877
Open

RDKEMW-11877: Metrics Collection for Player Interface Public APIs - Phase1#66
nejuma1 wants to merge 11 commits intofeature/RDKEMW-11881from
feature/RDKEMW-11877

Conversation

@nejuma1
Copy link
Copy Markdown

@nejuma1 nejuma1 commented Jan 21, 2026

RDKEMW-11877 : Metrics Collection for Player Interface Public APIs - Phase1
Reason for change : Integrating code for metrics collection
Test Procedure : Enable info logs to see metrics related logs
Priority : P1
Risks : None
Signed-off-by : nejumathoppil_nazar@comcast.com

nrames759 and others added 8 commits December 15, 2025 13:37
Merge pull request #52 from rdkcentral/feature/RDKEMW-9809
Reason for change : Integrating code for metrics collection
Test Procedure : Enable info logs to see metrics related logs
Priority : P1
Risks : None
Signed-off-by : nejumathoppil_nazar@comcast.com
@nejuma1 nejuma1 requested a review from a team as a code owner January 21, 2026 11:17
Copilot AI review requested due to automatic review settings January 21, 2026 11:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements Phase 1 of metrics collection for Player Interface Public APIs by introducing a profiling infrastructure and comprehensive test coverage for DRM key management functionality.

Changes:

  • Added performance profiling infrastructure with MW_PROFILE_FUNCTION() macro
  • Implemented extensive test suites for PlayerUtils (RawKeyToKeyId) and DrmSessionManager (multi-key validation)
  • Updated base64_Decode API signature across codebase to include explicit length parameter

Reviewed changes

Copilot reviewed 39 out of 39 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
PerfProfiler.h/cpp New profiling infrastructure using scoped timers for function execution tracking
InterfacePlayerRDK.cpp Added profiling macros to 40+ public API functions
CMakeLists.txt Added ENABLE_MW_PROFILING option and build configuration
test/utests/tests/PlayerUtilsTests/* New comprehensive tests for RawKeyToKeyId hex conversion function
test/utests/tests/DrmSessionManagerTests/* New tests for multi-key DRM scenarios with real PSSH data
test/utests/tests/OCDMSessionAdapter/KeyUpdateTests.cpp New tests for OCDM key update functionality
drm/ocdm/opencdmsessionadapter.cpp Refactored keyUpdateOCDM to handle usable keys tracking consistently
drm/DrmSessionManager.cpp Enhanced ValidateMultiKeySlot with improved key normalization logic
baseConversion/_base64.* Removed overloaded base64_Decode, unified signature with explicit length
externals/contentsecuritymanager/* Fixed spelling errors and added profiling macros
test/utests/mocks/* Updated mocks and added new MockDrmSessionFactory
test/utests/fakes/* Added fake implementations for ContentSecurityManager components

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// Get all key IDs from helper
std::map<int, std::vector<uint8_t>> keyIDs;
drmHelper->getKeys(keyIDs);
ASSERT_EQ(keyIDs.size(), 3); // Should have 3 key IDs (duplicates)
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states "Should have 3 key IDs (duplicates)" but Widevine helpers typically deduplicate keys. This comment should be verified against actual Widevine helper behavior. If keys are deduplicated, the expected value should be 1, not 3, and the comment should reflect that.

Copilot uses AI. Check for mistakes.
Comment on lines +169 to +173
PerfProfiler.h
)
if(ENABLE_MW_PROFILING)
list(APPEND LIBPLAYERGSTINTERFACE_HEADERS PerfProfiler.h)
endif()
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PerfProfiler.h is added to the LIBPLAYERGSTINTERFACE_HEADERS list twice: once unconditionally on line 169, and then conditionally on lines 171-173 if ENABLE_MW_PROFILING is enabled. This will result in duplicate entries when profiling is enabled. The unconditional addition on line 169 should be removed since the conditional block already handles adding it when needed.

Copilot uses AI. Check for mistakes.
Comment on lines +210 to +214
PerfProfiler.h
DESTINATION include)
if(ENABLE_MW_PROFILING)
install(FILES PerfProfiler.h DESTINATION include)
endif()
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PerfProfiler.h is listed in the install FILES command twice: once unconditionally on line 210, and then conditionally on lines 212-214 if ENABLE_MW_PROFILING is enabled. This will result in duplicate installation entries when profiling is enabled. The unconditional addition on line 210 should be removed since the conditional block already handles installing it when needed.

Copilot uses AI. Check for mistakes.
Comment on lines +228 to +232
PerfProfiler.cpp
)
if(ENABLE_MW_PROFILING)
list(APPEND SOURCES PerfProfiler.cpp)
endif()
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PerfProfiler.cpp is added to the SOURCES list twice: once unconditionally on line 228, and then conditionally on lines 230-232 if ENABLE_MW_PROFILING is enabled. This will result in duplicate source file entries when profiling is enabled, potentially causing build errors. The unconditional addition on line 228 should be removed since the conditional block already handles adding it when needed.

Copilot uses AI. Check for mistakes.
// Get extracted key IDs
std::map<int, std::vector<uint8_t>> keyIDs;
drmHelper->getKeys(keyIDs);
ASSERT_EQ(keyIDs.size(), 2); // Should have exactly 1 key (content ID should not be counted)
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says "Should have exactly 1 key (content ID should not be counted)" but the assertion expects size to be 2. This is inconsistent. Based on the comment, either the assertion should be ASSERT_EQ(keyIDs.size(), 1), or the comment should be updated to clarify that there is "1 key ID + 1 content ID = 2 total entries".

Copilot uses AI. Check for mistakes.
drmHelper->getKeys(keyIDs);

// Should have 3 key IDs + 1 content ID = 4 total entries
ASSERT_EQ(keyIDs.size(), 4);
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says "Should have 3 key IDs + 1 content ID = 4 total entries" but the assertion expects size to be 4. The math is correct (3 key IDs + 1 content ID = 4), so this is accurate. However, earlier in line 960, the comment says "Should have 3 key IDs + 1 content ID = 4 total entries" which should be verified for consistency with the actual data structure.

Copilot uses AI. Check for mistakes.
* If not stated otherwise in this file or this component's license file the
* following copyright and licenses apply:
*
* Copyright 2024 RDK Management
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The copyright year in this file header is 2024, but other new files in this PR use 2025. For consistency with the rest of the PR, this should be updated to 2025.

Suggested change
* Copyright 2024 RDK Management
* Copyright 2025 RDK Management

Copilot uses AI. Check for mistakes.
// Get all key IDs from helper
std::map<int, std::vector<uint8_t>> keyIDs;
drmHelper->getKeys(keyIDs);
ASSERT_EQ(keyIDs.size(), 6); // Should have 5 key IDs
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says "Should have 5 key IDs" but the assertion checks for 6. This inconsistency between the comment and the code logic should be corrected. Either the comment should be updated to "Should have 6 key IDs (5 key IDs + 1 content ID)" or the expected value in the assertion should match the comment.

Copilot uses AI. Check for mistakes.
// Get key IDs
std::map<int, std::vector<uint8_t>> keyIDs;
drmHelper->getKeys(keyIDs);
ASSERT_EQ(keyIDs.size(), 2); // Should have 1 key ID
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states "Should have 1 key ID" but the assertion checks for 2 entries. This inconsistency should be corrected. Based on the context in other tests where content IDs are also counted, the comment should likely be updated to clarify that there is "1 key ID + 1 content ID = 2 total entries".

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


1 out of 2 committers have signed the CLA.
✅ (narenr94)[https://github.com/narenr94]
@nejuma1
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

Copilot AI review requested due to automatic review settings January 29, 2026 11:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 39 out of 39 changed files in this pull request and generated 11 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +212 to 217
if(ENABLE_MW_PROFILING)
install(FILES PerfProfiler.h DESTINATION include)
endif()

set(SOURCES
InterfacePlayerRDK.cpp
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PerfProfiler.h is already part of the install(FILES ...) list, but it’s installed again under if(ENABLE_MW_PROFILING). This duplicates the install rule; keep a single install path for the header.

Suggested change
if(ENABLE_MW_PROFILING)
install(FILES PerfProfiler.h DESTINATION include)
endif()
set(SOURCES
InterfacePlayerRDK.cpp
set(SOURCES
InterfacePlayerRDK.cpp
InterfacePlayerRDK.cpp

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +41
MockDrmSessionFactory* g_MockDrmSessionFactory = nullptr;

/**
* @brief Fake implementation of GetDrmSession
*
* If g_MockDrmSessionFactory is set, delegates to the mock.
* Otherwise returns nullptr.
*/
DrmSession* DrmSessionFactory::GetDrmSession(DrmHelperPtr drmHelper, DrmCallbacks* drmCallbacks)
{
if (g_MockDrmSessionFactory)
{
return g_MockDrmSessionFactory->GetDrmSession(drmHelper, drmCallbacks);
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mock global is declared as g_mockDrmSessionFactory in MockDrmSessionFactory.h, but this fake defines/uses g_MockDrmSessionFactory. With the current mismatch, code including the header can’t set the pointer that DrmSessionFactory::GetDrmSession() checks. Rename to a single consistent global (and ensure it’s declared in the header used by tests).

Suggested change
MockDrmSessionFactory* g_MockDrmSessionFactory = nullptr;
/**
* @brief Fake implementation of GetDrmSession
*
* If g_MockDrmSessionFactory is set, delegates to the mock.
* Otherwise returns nullptr.
*/
DrmSession* DrmSessionFactory::GetDrmSession(DrmHelperPtr drmHelper, DrmCallbacks* drmCallbacks)
{
if (g_MockDrmSessionFactory)
{
return g_MockDrmSessionFactory->GetDrmSession(drmHelper, drmCallbacks);
MockDrmSessionFactory* g_mockDrmSessionFactory = nullptr;
/**
* @brief Fake implementation of GetDrmSession
*
* If g_mockDrmSessionFactory is set, delegates to the mock.
* Otherwise returns nullptr.
*/
DrmSession* DrmSessionFactory::GetDrmSession(DrmHelperPtr drmHelper, DrmCallbacks* drmCallbacks)
{
if (g_mockDrmSessionFactory)
{
return g_mockDrmSessionFactory->GetDrmSession(drmHelper, drmCallbacks);

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +84
// Create mocks before using them
g_mockOpenCdmSessionAdapter = new NiceMock<MockOpenCdmSessionAdapter>();
g_mockopencdm = new NiceMock<MockOpenCdm>();
g_mockMemorySystem = new NiceMock<MockDrmMemorySystem>();
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

g_mockopencdm is allocated earlier in SetUp(), and then allocated again here without deleting the first instance. This leaks the first mock and can drop any expectations on it. Please allocate it only once (or delete before reassigning).

Copilot uses AI. Check for mistakes.
{
mDefaultKeySlot = it.first;
MW_LOG_WARN("setDefaultKeyID : %s slot : %d", cencData.c_str(), mDefaultKeySlot);
MW_LOG_WARN("setDefaultKeyID : %s slot : %d", PlayerLogManager::getHexDebugStr(defaultKeyID).c_str(), mDefaultKeySlot);
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setDefaultKeyID() logs the (hex) key ID at WARN. If this is expected to run in production, consider lowering the log level or gating it behind a debug/profiling flag to avoid noisy logs and potential identifier exposure.

Copilot uses AI. Check for mistakes.
Comment on lines +215 to +219
// Print all key IDs for debugging
for (const auto& keyPair : mKeyIDs) {
std::string keyStr = PlayerLogManager::getHexDebugStr(keyPair.second);
MW_LOG_DEBUG("Key ID [%d]: %s", keyPair.first, keyStr.c_str());
}
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getKey() now logs every Key ID on every call. This can become very noisy and adds work to a frequently-called method. Consider removing the per-call loop, logging only on demand, or guarding it behind a debug/profiling flag.

Suggested change
// Print all key IDs for debugging
for (const auto& keyPair : mKeyIDs) {
std::string keyStr = PlayerLogManager::getHexDebugStr(keyPair.second);
MW_LOG_DEBUG("Key ID [%d]: %s", keyPair.first, keyStr.c_str());
}

Copilot uses AI. Check for mistakes.
Comment on lines +796 to +799
std::map<int, std::vector<uint8_t>> keyIDs;
drmHelper->getKeys(keyIDs);
ASSERT_EQ(keyIDs.size(), 2); // Should have exactly 1 key (content ID should not be counted)

Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same inconsistency here: ASSERT_EQ(keyIDs.size(), 2) but the comment says there should be exactly 1 key and that content-id should not be counted. Please update the expectation/comment to match what WidevineDrmHelper::getKeys() actually returns in this scenario.

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +33
option(ENABLE_MW_PROFILING "Enable middleware profiling" ON)

if(ENABLE_MW_PROFILING)
add_definitions(-DENABLE_MW_PROFILING)
endif()
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ENABLE_MW_PROFILING is defaulted to ON, which makes profiling instrumentation (timers + MW_LOG_INFO per call) enabled for all builds by default. Given the number of MW_PROFILE_FUNCTION() call sites in hot paths (e.g., InterfacePlayerRDK), this can introduce significant runtime overhead and log volume unless explicitly turned off. Consider defaulting this option to OFF (or gating it by build type) and enabling it only for profiling builds.

Copilot uses AI. Check for mistakes.
Comment on lines +171 to +173
if(ENABLE_MW_PROFILING)
list(APPEND LIBPLAYERGSTINTERFACE_HEADERS PerfProfiler.h)
endif()
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PerfProfiler.h is already listed in LIBPLAYERGSTINTERFACE_HEADERS, but it’s appended again under if(ENABLE_MW_PROFILING), which duplicates the entry. Keep it only once (either unconditional, or only under the option).

Suggested change
if(ENABLE_MW_PROFILING)
list(APPEND LIBPLAYERGSTINTERFACE_HEADERS PerfProfiler.h)
endif()

Copilot uses AI. Check for mistakes.
Comment on lines +230 to +232
if(ENABLE_MW_PROFILING)
list(APPEND SOURCES PerfProfiler.cpp)
endif()
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PerfProfiler.cpp is included in SOURCES unconditionally and then appended again under if(ENABLE_MW_PROFILING). This duplicates the source entry and can result in redundant build rules; include it only once.

Suggested change
if(ENABLE_MW_PROFILING)
list(APPEND SOURCES PerfProfiler.cpp)
endif()

Copilot uses AI. Check for mistakes.
Comment on lines +455 to +460
{
std::lock_guard<std::mutex> lock(m_usableKeysMutex);
return m_usableKeys;
} No newline at end of file
}
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getUsableKeys() takes the mutex but returns a reference to m_usableKeys after the lock is released. Callers will iterate the returned reference without holding the mutex, so concurrent updates in keyUpdateOCDM() can still race and invalidate iterators. Consider returning a copy (snapshot) or changing the API to provide a thread-safe way to access the usable-keys list.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants