1e41f4b71Sopenharmony_ci# DRM Media Key Session Management (C/C++)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciThe **MediaKeySystem** class of the DRM module supports media key management and media decryption. **MediaKeySession** instances are created and destroyed by **MediaKeySystem** instances.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci## How to Develop
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciRead [DRM](../../reference/apis-drm-kit/_drm.md) for the API reference.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci1. Import the NDK, which provides DRM-related attributes and methods.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci   ```c++
12e41f4b71Sopenharmony_ci    #include "multimedia/drm_framework/native_drm_common.h"
13e41f4b71Sopenharmony_ci    #include "multimedia/drm_framework/native_drm_err.h"
14e41f4b71Sopenharmony_ci    #include "multimedia/drm_framework/native_mediakeysession.h"
15e41f4b71Sopenharmony_ci    #include "multimedia/drm_framework/native_mediakeysystem.h"
16e41f4b71Sopenharmony_ci   ```
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci2. Link the DRM NDK dynamic library in the CMake script.
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci   ```txt
21e41f4b71Sopenharmony_ci    target_link_libraries(PUBLIC libnative_drm.so)
22e41f4b71Sopenharmony_ci   ```
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ci3. Declare the MediaKeySystem event listener callback.
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci    ```c++
27e41f4b71Sopenharmony_ci    // This callback applies to the scenario where there is only one MediaKeySystem instance.
28e41f4b71Sopenharmony_ci    static Drm_ErrCode SessoinEventCallBack(DRM_EventType  eventType, uint8_t *info, int32_t infoLen, char *extra)
29e41f4b71Sopenharmony_ci    {
30e41f4b71Sopenharmony_ci        return DRM_ERR_OK;
31e41f4b71Sopenharmony_ci    }
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci    static Drm_ErrCode SessoinKeyChangeCallBack(DRM_KeysInfo *keysInfo, bool newKeysAvailable)
34e41f4b71Sopenharmony_ci    {
35e41f4b71Sopenharmony_ci        return DRM_ERR_OK;
36e41f4b71Sopenharmony_ci    }
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ci    // This callback applies to the scenario where there are multiple MediaKeySystem instances.
39e41f4b71Sopenharmony_ci    static Drm_ErrCode SessoinEventCallBackWithObj(MediaKeySession *mediaKeySessoin, DRM_EventType eventType, uint8_t *info, int32_t infoLen, char *extra)
40e41f4b71Sopenharmony_ci    {
41e41f4b71Sopenharmony_ci        return DRM_ERR_OK;
42e41f4b71Sopenharmony_ci    }
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci    static Drm_ErrCode SessoinKeyChangeCallBackWithObj(MediaKeySession *mediaKeySessoin, DRM_KeysInfo *keysInfo, bool hasNewGoodKeys)
45e41f4b71Sopenharmony_ci    {
46e41f4b71Sopenharmony_ci        return DRM_ERR_OK;
47e41f4b71Sopenharmony_ci    }
48e41f4b71Sopenharmony_ci    ```
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_ci4. Set the MediaKeySystem event listener callback.
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ci    ```c++
53e41f4b71Sopenharmony_ci    // This callback applies to the scenario where there is only one MediaKeySystem instance.
54e41f4b71Sopenharmony_ci    MediaKeySession_Callback sessionCallback = { SessoinEventCallBack, SessoinKeyChangeCallBack };
55e41f4b71Sopenharmony_ci    Drm_ErrCode ret = OH_MediaKeySession_SetMediaKeySessionCallback(mediaKeySession, &sessionCallback);
56e41f4b71Sopenharmony_ci    if (ret != DRM_ERR_OK) {
57e41f4b71Sopenharmony_ci        printf("OH_MediaKeySession_SetMediaKeySessionCallback failed.");
58e41f4b71Sopenharmony_ci    }
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_ci    // This callback applies to the scenario where there are multiple MediaKeySystem instances.
61e41f4b71Sopenharmony_ci    OH_MediaKeySession_Callback sessionCallback = { SessoinEventCallBackWithObj, SessoinKeyChangeCallBackWithObj };
62e41f4b71Sopenharmony_ci    ret = OH_MediaKeySession_SetCallback(mediaKeySession, &sessionCallback);
63e41f4b71Sopenharmony_ci    if (ret != DRM_ERR_OK) {
64e41f4b71Sopenharmony_ci        printf("OH_MediaKeySession_SetCallback failed.");
65e41f4b71Sopenharmony_ci    }
66e41f4b71Sopenharmony_ci    ```
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ci5. Generate a media key request and process its response.
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci    ```c++
71e41f4b71Sopenharmony_ci    DRM_MediaKeyRequest mediaKeyRequest;
72e41f4b71Sopenharmony_ci    DRM_MediaKeyRequestInfo info;
73e41f4b71Sopenharmony_ci    // initData corresponds to the PSSH data in the stream. Pass in the actual data.
74e41f4b71Sopenharmony_ci    unsigned char initData[128] = {0x00};
75e41f4b71Sopenharmony_ci    memset_s(&info, sizeof(DRM_MediaKeyRequestInfo), 0, sizeof(DRM_MediaKeyRequestInfo));
76e41f4b71Sopenharmony_ci    info.initDataLen = sizeof(initData);
77e41f4b71Sopenharmony_ci    info.type = MEDIA_KEY_TYPE_ONLINE;
78e41f4b71Sopenharmony_ci    memcpy_s(info.mimeType, sizeof("video/avc"), (char *)"video/avc", sizeof("video/avc"));
79e41f4b71Sopenharmony_ci    memcpy_s(info.initData, sizeof(initData), initData, sizeof(initData));
80e41f4b71Sopenharmony_ci    memcpy_s(info.optionName[0], sizeof("optionalDataName"), (char *)"optionalDataName", sizeof("optionalDataName"));
81e41f4b71Sopenharmony_ci    memcpy_s(info.optionData[0], sizeof("optionalDataValue"), (char *)"optionalDataValue", sizeof("optionalDataValue"));
82e41f4b71Sopenharmony_ci    info.optionsCount = 1;
83e41f4b71Sopenharmony_ci    ret = OH_MediaKeySession_GenerateMediaKeyRequest(mediaKeySession, &info, &mediaKeyRequest);
84e41f4b71Sopenharmony_ci    if (ret != DRM_ERR_OK) {
85e41f4b71Sopenharmony_ci        printf("OH_MediaKeySession_GenerateMediaKeyRequest failed.");
86e41f4b71Sopenharmony_ci    }
87e41f4b71Sopenharmony_ci    /* The composition of an offline media key ID varies according to the DRM scheme. You can obtain an ID in either of the following ways:
88e41f4b71Sopenharmony_ci      1. The application calls OH_MediaKeySystem_GetOfflineMediaKeyIds to obtain the ID.
89e41f4b71Sopenharmony_ci      2. The application requests the DRM service through the network, obtains a keySessionResponse, and sends the response to OH_MediaKeySession_ProcessMediaKeyResponse for parsing.
90e41f4b71Sopenharmony_ci         An offline media key ID is obtained. The maximum length of a media key ID is 128. The following code is an example. Set the media key ID based on the actual media key data and length.
91e41f4b71Sopenharmony_ci    */
92e41f4b71Sopenharmony_ci    unsigned char mediaKeyId[26] = {0x00};
93e41f4b71Sopenharmony_ci    int32_t mediaKeyIdLen = 26;
94e41f4b71Sopenharmony_ci    // The maximum length of a media key response is 12288. Enter the actual length.
95e41f4b71Sopenharmony_ci    unsigned char mediaKeyResponse[12288] = {0x00};
96e41f4b71Sopenharmony_ci    int32_t mediaKeyResponseLen = 12288;
97e41f4b71Sopenharmony_ci    ret = OH_MediaKeySession_ProcessMediaKeyResponse(mediaKeySession, mediaKeyResponse,
98e41f4b71Sopenharmony_ci        mediaKeyResponseLen, mediaKeyId, &mediaKeyIdLen);
99e41f4b71Sopenharmony_ci    if (ret != DRM_ERR_OK) {
100e41f4b71Sopenharmony_ci        printf("OH_MediaKeySession_ProcessMediaKeyResponse failed.");
101e41f4b71Sopenharmony_ci    }
102e41f4b71Sopenharmony_ci    ```
103e41f4b71Sopenharmony_ci
104e41f4b71Sopenharmony_ci6. (Optional) Check the media key status of the media key session.
105e41f4b71Sopenharmony_ci
106e41f4b71Sopenharmony_ci    ```c++
107e41f4b71Sopenharmony_ci    DRM_MediaKeyStatus mediaKeyStatus;
108e41f4b71Sopenharmony_ci    ret = OH_MediaKeySession_CheckMediaKeyStatus(mediaKeySession, &mediaKeyStatus);
109e41f4b71Sopenharmony_ci    if (ret != DRM_ERR_OK) {
110e41f4b71Sopenharmony_ci        printf("OH_MediaKeySession_CheckMediaKeyStatus failed.");
111e41f4b71Sopenharmony_ci    }
112e41f4b71Sopenharmony_ci    ```
113e41f4b71Sopenharmony_ci
114e41f4b71Sopenharmony_ci7. (Optional) Clear all media keys in the media key session.
115e41f4b71Sopenharmony_ci
116e41f4b71Sopenharmony_ci    ```c++
117e41f4b71Sopenharmony_ci    ret = OH_MediaKeySession_ClearMediaKeys(mediaKeySession);
118e41f4b71Sopenharmony_ci    if (ret != DRM_ERR_OK) {
119e41f4b71Sopenharmony_ci        printf("OH_MediaKeySession_ClearMediaKeys failed.");
120e41f4b71Sopenharmony_ci    }
121e41f4b71Sopenharmony_ci   ```
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ci8. (Optional) Generate an offline media key release request and process its response.
124e41f4b71Sopenharmony_ci
125e41f4b71Sopenharmony_ci    ```c++
126e41f4b71Sopenharmony_ci    uint8_t releaseRequest[MAX_MEDIA_KEY_REQUEST_DATA_LEN];
127e41f4b71Sopenharmony_ci    int32_t releaseRequestLen = MAX_MEDIA_KEY_REQUEST_DATA_LEN;
128e41f4b71Sopenharmony_ci    ret = OH_MediaKeySession_GenerateOfflineReleaseRequest(mediaKeySession,
129e41f4b71Sopenharmony_ci        mediaKeyId, mediaKeyIdLen, releaseRequest, &releaseRequestLen);
130e41f4b71Sopenharmony_ci    if (ret != DRM_ERR_OK) {
131e41f4b71Sopenharmony_ci        printf("OH_MediaKeySession_GenerateOfflineReleaseRequest failed.");
132e41f4b71Sopenharmony_ci    }
133e41f4b71Sopenharmony_ci    // keyReleaseResponse is obtained from the DRM service through the network request using the request body releaseRequest. Pass in the actual data obtained.
134e41f4b71Sopenharmony_ci    unsigned char keyReleaseResponse[12288] = {0x00};
135e41f4b71Sopenharmony_ci    int32_t keyReleaseResponseLen = 12288;
136e41f4b71Sopenharmony_ci    ret = OH_MediaKeySession_ProcessOfflineReleaseResponse(mediaKeySession, mediaKeyId, mediaKeyIdLen,
137e41f4b71Sopenharmony_ci       keyReleaseResponse, keyReleaseResponseLen);
138e41f4b71Sopenharmony_ci    if (ret != DRM_ERR_OK) {
139e41f4b71Sopenharmony_ci        printf("OH_MediaKeySession_ProcessOfflineReleaseResponse failed.");
140e41f4b71Sopenharmony_ci    }
141e41f4b71Sopenharmony_ci    ```
142e41f4b71Sopenharmony_ci
143e41f4b71Sopenharmony_ci9. (Optional) Restore offline media keys.
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ci    ```c++
146e41f4b71Sopenharmony_ci    // Load the media key with the specified media key ID to the current session. The loaded media key can belong to the current session or another session.
147e41f4b71Sopenharmony_ci    ret = OH_MediaKeySession_RestoreOfflineMediaKeys(mediaKeySession, mediaKeyId, mediaKeyIdLen);
148e41f4b71Sopenharmony_ci    if (ret != DRM_ERR_OK) {
149e41f4b71Sopenharmony_ci        printf("OH_MediaKeySession_RestoreOfflineMediaKeys failed.");
150e41f4b71Sopenharmony_ci    }
151e41f4b71Sopenharmony_ci   ```
152e41f4b71Sopenharmony_ci
153e41f4b71Sopenharmony_ci10. (Optional) Call **OH_MediaKeySession_GetContentProtectionLevel** in the **MediaKeySession** class to obtain the content protection level of the current session.
154e41f4b71Sopenharmony_ci
155e41f4b71Sopenharmony_ci    ```c++
156e41f4b71Sopenharmony_ci    DRM_ContentProtectionLevel sessionContentProtectionLevel;
157e41f4b71Sopenharmony_ci    ret = OH_MediaKeySession_GetContentProtectionLevel(mediaKeySession,
158e41f4b71Sopenharmony_ci        &sessionContentProtectionLevel);
159e41f4b71Sopenharmony_ci    if (ret != DRM_ERR_OK) {
160e41f4b71Sopenharmony_ci        printf("OH_MediaKeySession_GetContentProtectionLevel failed.");
161e41f4b71Sopenharmony_ci    }
162e41f4b71Sopenharmony_ci    ```
163e41f4b71Sopenharmony_ci
164e41f4b71Sopenharmony_ci11. (Optional) Check whether secure decoding is required.
165e41f4b71Sopenharmony_ci
166e41f4b71Sopenharmony_ci    ```c++
167e41f4b71Sopenharmony_ci    bool requireSecureDecoder;
168e41f4b71Sopenharmony_ci    ret = OH_MediaKeySession_RequireSecureDecoderModule(mediaKeySession, "video/avc", &requireSecureDecoder);
169e41f4b71Sopenharmony_ci    if (ret != DRM_ERR_OK) {
170e41f4b71Sopenharmony_ci        printf("OH_MediaKeySession_RequireSecureDecoderModule failed.");
171e41f4b71Sopenharmony_ci    }
172e41f4b71Sopenharmony_ci    ```
173