1# DRM Media Key System Management (C/C++)
2
3Using the **MediaKeySystem** class of the DRM module, you can manage **MediaKeySystem** instances, generate media key system requests to obtain DRM certificates, process responses to these requests, manage media key sessions, manage offline media keys, and obtain DRM statistics and device configuration information. Before using DRM Kit, check whether the device supports the DRM capabilities of a specific DRM scheme. In DRM Kit, the DRM scheme exists as a plug-in.
4
5## How to Develop
6
7Read [DRM](../../reference/apis-drm-kit/_drm.md) for the API reference.
8
91. Import the NDK.
10
11   ```c++
12    #include "multimedia/drm_framework/native_drm_common.h"
13    #include "multimedia/drm_framework/native_drm_err.h"
14    #include "multimedia/drm_framework/native_mediakeysession.h"
15    #include "multimedia/drm_framework/native_mediakeysystem.h"
16   ```
17
182. Link the DRM NDK dynamic library in the CMake script.
19
20   ```txt
21    target_link_libraries(PUBLIC libnative_drm.so)
22   ```
23
243. Check whether the device supports the DRM scheme based on the specified name, MIME type, and content protection level.
25
26   ```c++
27    bool isSupported = OH_MediaKeySystem_IsSupported3("com.clearplay.drm", "video/avc", CONTENT_PROTECTION_LEVEL_SW_CRYPTO);
28    if (isSupported != true) {
29        printf("The device does not support the content protection level.");
30    }
31   ```
32
334. (Optional) Obtain the name and ID list of the DRM schemes supported by the device.
34
35   ```c++
36    uint32_t count = 1; // count indicates the number of DRM plug-ins supported by the device. Pass in the actual number.
37    DRM_MediaKeySystemDescription descriptions[1];
38    memset(descriptions, 0, sizeof(descriptions));
39    Drm_ErrCode ret = OH_MediaKeySystem_GetMediaKeySystems(descriptions, &count);
40    if (ret != DRM_ERR_OK) {
41        printf("OH_MediaKeySystem_GetMediaKeySystems failed.");
42    }
43   ```
44
455. Create a **MediaKeySystem** instance.
46
47   ```c++
48    MediaKeySystem *mediaKeySystem = NULL;
49    Drm_ErrCode ret = OH_MediaKeySystem_Create("com.clearplay.drm", &mediaKeySystem);
50    if (ret != DRM_ERR_OK) {
51        printf("OH_MediaKeySystem_Create failed.");
52    }
53   ```
54
556. (Optional) Declare the MediaKeySystem event listener callback.
56
57   ```c++
58     // This callback applies to the scenario where there are multiple MediaKeySystem instances.
59    static Drm_ErrCode SystemCallBack(DRM_EventType eventType, uint8_t *info, int32_t infoLen, char *extra)
60    {
61        printf("SystemCallBack");
62    }
63    // This callback applies to the scenario where there is only one MediaKeySystem instance.
64    static Drm_ErrCode SystemCallBackWithObj(MediaKeySystem *mediaKeySystem, DRM_EventType eventType,
65    uint8_t *info, int32_t infoLen, char *extra)
66    {
67        printf("TestSystemCallBackWithObj");
68    }
69   ```
70
717. (Optional) Set the MediaKeySystem event listener callback.
72
73   ```c++
74     // This callback applies to the scenario where there are multiple MediaKeySystem instances.
75    Drm_ErrCode ret = OH_MediaKeySystem_SetMediaKeySystemCallback(mediaKeySystem, SystemCallBack);
76    if (ret != DRM_ERR_OK) {
77        printf("OH_MediaKeySystem_SetMediaKeySystemCallback failed.");
78    }
79
80    // This callback applies to the scenario where there is only one MediaKeySystem instance.
81    ret = OH_MediaKeySystem_SetCallback(mediaKeySystem, SystemCallBackWithObj);
82    if (ret != DRM_ERR_OK) {
83        printf("OH_MediaKeySystem_SetCallback failed.");
84    }
85   ```
86
878. Create a **MediaKeySession** instance.
88
89   ```c++
90    MediaKeySession *mediaKeySession = nullptr;
91    DRM_ContentProtectionLevel contentProtectionLevel = CONTENT_PROTECTION_LEVEL_SW_CRYPTO;
92    ret = OH_MediaKeySystem_CreateMediaKeySession(mediaKeySystem, &contentProtectionLevel, &mediaKeySession);
93    if (ret != DRM_ERR_OK || mediaKeySession == nullptr) {
94        printf("OH_MediaKeySystem_CreateMediaKeySession failed.");
95    }
96   ```
97
989. Check the DRM certificate status of the device. If the device does not have a DRM certificate or the DRM certificate status is abnormal, generate a provision request to obtain a DRM certificate and process its response.
99
100   ```c++
101    unsigned char request[12288] = { 0x00 };  // The maximum length of a provision request is 12288. Apply for memory based on the actual length.
102    int32_t requestLen = 12288;
103    // The maximum length of the DRM service URL is 2048.
104    char defaultUrl[2048] = { 0x00 };
105    int32_t defaultUrlLen = 2048;
106    DRM_CertificateStatus certStatus = CERT_STATUS_INVALID;
107    // Check the DRM certificate status of the device.
108    ret = OH_MediaKeySystem_GetCertificateStatus(mediaKeySystem, &certStatus);
109    if (ret == DRM_ERR_OK && certStatus == CERT_STATUS_NOT_PROVISIONED) {
110        ret = OH_MediaKeySystem_GenerateKeySystemRequest(mediaKeySystem, request, &requestLen, defaultUrl,
111            defaultUrlLen);
112        /*
113          The application sends a provision request to the DRM service through a network request, obtains a response,
114          and sets the response to the device. Pass in the actual value and length.
115        */
116        unsigned char KeySystemResponse[12288] = {0x00};
117        ret = OH_MediaKeySystem_ProcessKeySystemResponse(mediaKeySystem, KeySystemResponse, sizeof(KeySystemResponse));
118        if (ret != DRM_ERR_OK) {
119            printf("OH_MediaKeySystem_ProcessKeySystemResponse failed.");
120        }
121    }
122   ```
123
12410. (Optional) Obtain the IDs of offline media keys, obtain their status, and clear the keys.
125
126       ```c++
127        DRM_OfflineMediakeyIdArray offlineMediaKeyIds;
128        ret = OH_MediaKeySystem_GetOfflineMediaKeyIds(mediaKeySystem, &offlineMediaKeyIds);
129        if (ret != DRM_ERR_OK) {
130            printf("OH_MediaKeySystem_GetOfflineMediaKeyIds failed.");
131        }
132        DRM_OfflineMediaKeyStatus OfflineMediaKeyStatus = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN;
133        ret = OH_MediaKeySystem_GetOfflineMediaKeyStatus(mediaKeySystem, offlineMediaKeyIds.ids[0], offlineMediaKeyIds.idsLen[0], &OfflineMediaKeyStatus);
134        if (ret != DRM_ERR_OK) {
135            printf("OH_MediaKeySystem_GetOfflineMediaKeyStatus failed.");
136        }
137        ret = OH_MediaKeySystem_ClearOfflineMediaKeys(mediaKeySystem, offlineMediaKeyIds.ids[0], offlineMediaKeyIds.idsLen[0]);
138        if (ret != DRM_ERR_OK) {
139            printf("OH_MediaKeySystem_ClearOfflineMediaKeys failed.");
140        }
141       ```
142
14311. (Optional) Set and obtain the DRM configuration information.
144
145    > **NOTE**
146    >
147    > The configuration information may vary according to the DRM scheme. The supported configuration item names are "vendor", "version", "description", "algorithms", "maxSessionNum", and "currentHDCPLevel." The DRM configuration information can be set only when the scheme supports the setting of configuration items.
148
149       ```c++
150        ret = OH_MediaKeySystem_SetConfigurationString(mediaKeySystem, "version", "2.0"); // Set the configuration information of the string type.
151        if (ret == DRM_ERR_OK) {
152            printf("MediaKeySystem_SetConfigurationString success");
153        } else {
154            printf("MediaKeySystem_SetConfigurationString failed. %d ", ret);
155        }
156        char value[32];
157        int32_t valueLen = 32;
158        // Obtain the value of a configuration item in the form of a string.
159        ret = OH_MediaKeySystem_GetConfigurationString(mediaKeySystem, "version", value, valueLen);
160        if (ret == DRM_ERR_OK) {
161            printf("OH_MediaKeySystem_GetConfigurationString success");
162        } else {
163            printf("OH_MediaKeySystem_GetConfigurationString failed. %d ", ret);
164        }
165        // Set the configuration information of the character array type based on the actual data and length.
166        uint8_t description[4] = {0x00, 0x00, 0x00, 0x00};
167        ret = OH_MediaKeySystem_SetConfigurationByteArray(mediaKeySystem, "description", description, sizeof(description)/sizeof(uint8_t));
168        if (ret == DRM_ERR_OK) {
169            printf("OH_MediaKeySystem_SetConfigurationByteArray success ");
170        } else {
171            printf("OH_MediaKeySystem_SetConfigurationByteArray failed. %d ", ret);
172        }
173         // Obtain the configuration information of the character array type. Pass in the actual data.
174        uint8_t descriptionValue[32];
175        int32_t descriptionValueLen = 32;
176        ret = OH_MediaKeySystem_GetConfigurationByteArray(mediaKeySystem, "description", descriptionValue, &descriptionValueLen);
177        if (ret == DRM_ERR_OK) {
178            printf("OH_MediaKeySystem_GetConfigurationByteArray success ");
179        } else {
180            printf("OH_MediaKeySystem_GetConfigurationByteArray failed. %d ", ret);
181        }
182       ```
183
18412. (Optional) Obtain the maximum content protection level supported by the device.
185
186       ```c++
187        DRM_ContentProtectionLevel contentProtectionLevel = CONTENT_PROTECTION_LEVEL_UNKNOWN;
188        ret = OH_MediaKeySystem_GetMaxContentProtectionLevel(mediaKeySystem, &contentProtectionLevel);
189        if (ret != DRM_ERR_OK) {
190            printf("OH_MediaKeySystem_GetMaxContentProtectionLevel failed.");
191        }
192       ```
193
19413. Destroy the **MediaKeySession** instance.
195
196       ```c++
197        ret = OH_MediaKeySession_Destroy(mediaKeySession);
198        if (ret != DRM_ERR_OK) {
199            printf("OH_MediaKeySession_Destroy failed.");
200        }
201       ```
202
20314. Destroy the **MediaKeySystem** instance.
204
205       ```c++
206        ret = OH_MediaKeySystem_Destroy(mediaKeySystem);
207        if (ret != DRM_ERR_OK) {
208            printf("OH_MediaKeySystem_Destroy failed.");
209        }
210       ```