Skip to content

Porting of MediaDRM changes from add-on#54

Merged
keithah merged 16 commits intoxbmc:masterfrom
CastagnaIT:addon_port
Feb 14, 2026
Merged

Porting of MediaDRM changes from add-on#54
keithah merged 16 commits intoxbmc:masterfrom
CastagnaIT:addon_port

Conversation

@CastagnaIT
Copy link
Copy Markdown
Contributor

@CastagnaIT CastagnaIT commented Feb 2, 2026

This PR ports all MediaDRM code changes used by the InputStream Adaptive add-on,
which will allow libandroidjni to be used as a direct dependency by ISA, making it easier to keep updated components rather than having to maintain the same code in two different repositories

Note: This PR simply ports the code as is, without updating it to any current Android API changes

Main changes:

  • Add clang-format (not related to PR, but i was going crazy formatting code without it...)
  • Add new constructor to CJNIClassLoader, add-on dont make use of CJNIContext since needs to have the class loader we initialize by APK path
  • JNIBase make SetSDKVersion public, this due to above point (CJNIContext not used)
  • Add new methods: getPropertyByteArray, queryKeyStatus, getSecurityLevel, getMaxSecurityLevel
  • Cleaning array casts code, with a safer casting of arrays.
    this partially revert 6aa528d
    since we can check jholder validity of contained object in advance
    without causing crashes due to null jholder array value.
    Instead about array casts now the cast method is able to handle
    null array by returning empty vector without crashes
  • Changed media DRM data type to make use of uint8_t to represent java byte data format instead of "char". Although previous "char" type may be similar to java "byte" in terms of values range, is not so appropriate for presenting data in C++, to note that uint8_t has also always been used on Widevine CDM interface as well, so IMO better provide consistency. Note i kept vector of "char" for sessionid intentionally (despite api use bytes). The sessionid is usually textual (at least on CDM) and even on Android despite being bytes is humanly readable as a string. Crypto methods (e.g. encrypt/decript) are unchanged, despite they should also handle data with uint8_t)

Code adjustments on kodi DRM parts: xbmc/xbmc#27812
ISA PR code changes: xbmc/inputstream.adaptive#1988

In the meantime, i have created this PR draft to show the changes and possibly allow for early feedback

Comment thread src/ClassLoader.cpp
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This will work, but since it's a different class, it would be more correct to create a new CJNIPathClassLoader class and add it to the PathClassLoader.cpp and .h files.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I thought it would be simpler, but class loaders are used by listeners e.g. CJNIMediaDrmOnEventListener,
if you want keep separate things, the only way i found is create an interface as follow:

class IJNIClassLoader : virtual public CJNIBase
{
public:
  jni::jhclass loadClass(std::string className);
};

where become

CJNIClassLoader : IJNIClassLoader 
CJNIPathClassLoader : IJNIClassLoader 

so listeners will use the pointer interface IJNIClassLoader to access to methods instead of CJNIClassLoader,
if you think it might be okay, let me know

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i pushed an alternative solution
where CJNIPathClassLoader can create the loader by using a static member CreateClassLoader
so that you can use same CJNIClassLoader object without make a lot of changes
what do you think?

PS. i dont have tested it yet

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I have done several tests, including trying a CJNIPathClassLoader class that inherits from CJNIClassLoader, but I am not convinced.

I think for now it would be best to incorporate the changes as they were in the add-on (in ClassLoader.cpp and .h). In the future, once the add-on uses the library and all this does not affect Kodi, we will look into separating these two classes if we consider it worthwhile.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

okay i restore the code

Comment thread src/MediaDrm.cpp Outdated
Comment thread src/MediaDrm.cpp Outdated
An addon initialize by using kodi APK path
example:

apkEnv = getenv("KODI_ANDROID_APK");
m_classLoader = std::make_shared<CJNIClassLoader>(apkEnv);
Avoid pass null object to get...array
@CastagnaIT CastagnaIT marked this pull request as ready for review February 8, 2026 09:58
@CastagnaIT CastagnaIT removed the WIP label Feb 8, 2026
@keithah
Copy link
Copy Markdown
Member

keithah commented Feb 14, 2026

@kodiai review

Copy link
Copy Markdown

@kodiai kodiai Bot left a comment

Choose a reason for hiding this comment

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

kodiai response

Decision: APPROVE

Issues: none

@keithah keithah merged commit 59b6850 into xbmc:master Feb 14, 2026
@CastagnaIT CastagnaIT deleted the addon_port branch February 14, 2026 19:26
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.

3 participants