• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "key_session_napi.h"
16 #include "media_key_system_napi.h"
17 #include "napi_param_utils.h"
18 #include "drm_trace.h"
19 #include "drm_error_code_napi.h"
20 #include "drm_api_operation.h"
21 
22 namespace OHOS {
23 namespace DrmStandard {
24 thread_local napi_ref MediaKeySystemNapi::sConstructor_ = nullptr;
25 thread_local sptr<MediaKeySystemImpl> MediaKeySystemNapi::sMediaKeySystemImpl_ = nullptr;
26 
MediaKeySystemNapi()27 MediaKeySystemNapi::MediaKeySystemNapi() : env_(nullptr), wrapper_(nullptr)
28 {
29     DRM_DEBUG_LOG("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
30 }
31 
~MediaKeySystemNapi()32 MediaKeySystemNapi::~MediaKeySystemNapi()
33 {
34     DRM_INFO_LOG("~MediaKeySystemNapi enter.");
35     DRM_DEBUG_LOG("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
36     if (wrapper_ != nullptr) {
37         napi_delete_reference(env_, wrapper_);
38     }
39     if (mediaKeySystemImpl_) {
40         mediaKeySystemImpl_ = nullptr;
41     }
42     if (mediaKeySystemCallbackNapi_) {
43         mediaKeySystemCallbackNapi_ = nullptr;
44     }
45 }
46 
Init(napi_env env,napi_value exports)47 napi_value MediaKeySystemNapi::Init(napi_env env, napi_value exports)
48 {
49     DRM_INFO_LOG("Init enter.");
50     napi_status status;
51     napi_value ctorObj;
52 
53     napi_property_descriptor properties[] = {
54         DECLARE_NAPI_FUNCTION("setConfigurationString", SetConfigurationString),
55         DECLARE_NAPI_FUNCTION("getConfigurationString", GetConfigurationString),
56         DECLARE_NAPI_FUNCTION("setConfigurationByteArray", SetConfigurationByteArray),
57         DECLARE_NAPI_FUNCTION("getConfigurationByteArray", GetConfigurationByteArray),
58         DECLARE_NAPI_FUNCTION("getMaxContentProtectionLevel", GetMaxContentProtectionLevel),
59         DECLARE_NAPI_FUNCTION("generateKeySystemRequest", GenerateKeySystemRequest),
60         DECLARE_NAPI_FUNCTION("processKeySystemResponse", ProcessKeySystemResponse),
61         DECLARE_NAPI_FUNCTION("createMediaKeySession", CreateMediaKeySession),
62         DECLARE_NAPI_FUNCTION("getStatistics", GetStatistics),
63         DECLARE_NAPI_FUNCTION("getCertificateStatus", GetCertificateStatus),
64         DECLARE_NAPI_FUNCTION("getOfflineMediaKeyIds", GetOfflineMediaKeyIds),
65         DECLARE_NAPI_FUNCTION("getOfflineMediaKeyStatus", GetOfflineMediaKeyStatus),
66         DECLARE_NAPI_FUNCTION("clearOfflineMediaKeys", ClearOfflineMediaKeys),
67         DECLARE_NAPI_FUNCTION("destroy", Destroy),
68         DECLARE_NAPI_FUNCTION("on", SetEventCallback),
69         DECLARE_NAPI_FUNCTION("off", UnsetEventCallback),
70     };
71 
72     napi_property_descriptor drm_static_properties[] = {
73         DECLARE_NAPI_STATIC_FUNCTION("createMediaKeySystem", CreateMediaKeySystemInstance),
74         DECLARE_NAPI_STATIC_FUNCTION("isMediaKeySystemSupported", IsMediaKeySystemSupported),
75         DECLARE_NAPI_STATIC_FUNCTION("getMediaKeySystems", GetMediaKeySystems),
76         DECLARE_NAPI_STATIC_FUNCTION("getMediaKeySystemUuid", GetMediaKeySystemUuid)
77     };
78 
79     status = napi_define_class(env, MEDIA_KEY_SYSTEM_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH, MediaKeySystemNapiConstructor,
80         nullptr, sizeof(properties) / sizeof(properties[PARAM0]), properties, &ctorObj);
81     DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define napi class");
82     status = napi_create_reference(env, ctorObj, 1, &sConstructor_);
83     DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to create napi reference");
84     status = napi_set_named_property(env, exports, MEDIA_KEY_SYSTEM_NAPI_CLASS_NAME, ctorObj);
85     DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to set napi named property");
86     status = napi_define_properties(env, exports, sizeof(drm_static_properties) / sizeof(drm_static_properties[0]),
87         drm_static_properties);
88     DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define static DrmNapi function");
89     return exports;
90 }
91 
MediaKeySystemNapiConstructor(napi_env env,napi_callback_info info)92 napi_value MediaKeySystemNapi::MediaKeySystemNapiConstructor(napi_env env, napi_callback_info info)
93 {
94     DrmTrace trace("MediaKeySystemNapi::MediaKeySystemNapiConstructor");
95     DRM_INFO_LOG("MediaKeySystemNapiConstructor enter.");
96     napi_value result = nullptr;
97     size_t argCount = 0;
98     napi_value jsThis = nullptr;
99 
100     napi_get_undefined(env, &result);
101 
102     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
103     DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "failed to napi_get_cb_info");
104 
105     if (status == napi_ok && jsThis != nullptr) {
106         std::unique_ptr<MediaKeySystemNapi> obj = std::make_unique<MediaKeySystemNapi>();
107         obj->env_ = env;
108         if (MediaKeySystemNapi::sMediaKeySystemImpl_ == nullptr) {
109             DRM_ERR_LOG("sMediaKeySystemImpl_ is null");
110             return result;
111         }
112         obj->mediaKeySystemImpl_ = MediaKeySystemNapi::sMediaKeySystemImpl_;
113         obj->mediaKeySystemCallbackNapi_ = new (std::nothrow) MediaKeySystemCallbackNapi(env);
114         obj->mediaKeySystemImpl_->SetCallback(obj->mediaKeySystemCallbackNapi_);
115         status = napi_wrap(env, jsThis, reinterpret_cast<void *>(obj.get()),
116             MediaKeySystemNapi::MediaKeySystemNapiDestructor, nullptr, nullptr);
117         if (status == napi_ok) {
118             ObjectRefMap<MediaKeySystemNapi>::Insert(obj.get());
119             obj.release();
120             return jsThis;
121         } else {
122             ObjectRefMap<MediaKeySystemNapi>::Erase(obj.get());
123             DRM_ERR_LOG("Failure wrapping js to native napi");
124         }
125     }
126 
127     return result;
128 }
129 
CreateMediaKeySystemInstance(napi_env env,napi_callback_info info)130 napi_value MediaKeySystemNapi::CreateMediaKeySystemInstance(napi_env env, napi_callback_info info)
131 {
132     DRM_INFO_LOG("CreateMediaKeySystemInstance enter.");
133     napi_status status;
134     napi_value result = nullptr;
135     napi_value ctor = nullptr;
136     napi_get_undefined(env, &result);
137     status = napi_get_reference_value(env, sConstructor_, &ctor);
138     if (status == napi_ok) {
139         size_t argc = ARGS_ONE;
140         napi_value argv[ARGS_ONE] = {0};
141         napi_value thisVar = nullptr;
142         DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
143         std::string drmSchemaName;
144         char nameBuffer[PATH_MAX] = { 0 };
145         size_t nameBufferLen = 0;
146         status = napi_get_value_string_utf8(env, argv[PARAM0], nameBuffer, PATH_MAX, &nameBufferLen);
147         if (status != napi_ok) {
148             NapiDrmError::ThrowError(env, "The param name is missing or too long.", DRM_NAPI_ERR_INVALID_VAL);
149             DRM_ERR_LOG("napi_get_value_string_utf8 failed!");
150             return result;
151         }
152         drmSchemaName = std::string(nameBuffer);
153         int32_t ret = MediaKeySystemFactoryImpl::GetInstance()->CreateMediaKeySystem(drmSchemaName,
154             &MediaKeySystemNapi::sMediaKeySystemImpl_);
155         if (ret != DRM_NAPI_ERR_OK) {
156             NapiDrmError::ThrowError(env, "create MediaKeySystem failed.",
157                 DrmInnerErrToNapiErrAPI12(static_cast<DrmInnerErrCode>(ret)));
158             DRM_ERR_LOG("CreateMediaKeySystem failed!");
159             return result;
160         }
161         status = napi_new_instance(env, ctor, 0, nullptr, &result);
162         MediaKeySystemNapi::sMediaKeySystemImpl_ = nullptr;
163         if (status == napi_ok) {
164             return result;
165         } else {
166             DRM_ERR_LOG("New instance could not be obtained");
167         }
168     }
169     NapiDrmError::ThrowError(env, "create MediaKeySystem failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
170     napi_get_undefined(env, &result);
171     return result;
172 }
173 
MediaKeySystemNapiDestructor(napi_env env,void * nativeObject,void * finalize)174 void MediaKeySystemNapi::MediaKeySystemNapiDestructor(napi_env env, void *nativeObject, void *finalize)
175 {
176     DrmTrace trace("MediaKeySystemNapi::MediaKeySystemNapiDestructor");
177     DRM_INFO_LOG("MediaKeySystemNapiDestructor enter.");
178     MediaKeySystemNapi *mediaKeySystemNapi = reinterpret_cast<MediaKeySystemNapi *>(nativeObject);
179     ObjectRefMap<MediaKeySystemNapi>::DecreaseRef(mediaKeySystemNapi);
180 }
181 
IsMediaKeySystemSupported(napi_env env,napi_callback_info info)182 napi_value MediaKeySystemNapi::IsMediaKeySystemSupported(napi_env env, napi_callback_info info)
183 {
184     DRM_INFO_LOG("IsMediaKeySystemSupported enter.");
185     napi_value result = nullptr;
186     size_t argc = ARGS_THREE;
187     napi_value argv[ARGS_THREE] = {0, 0, 0};
188     napi_value thisVar = nullptr;
189     napi_get_undefined(env, &result);
190     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
191     char buffer[PATH_MAX];
192     size_t length = 0;
193     if (napi_get_value_string_utf8(env, argv[PARAM0], buffer, PATH_MAX, &length) != napi_ok) {
194         DRM_ERR_LOG("Could not able to read drm plugin name argument!");
195         NapiDrmError::ThrowError(env, "Could not able to read drm plugin name argument!", DRM_NAPI_ERR_UNKNOWN);
196         return result;
197     }
198     std::string pluginName = std::string(buffer);
199     if (pluginName.length() == 0 || pluginName.length() > MAX_STRING_SIZE) {
200         DRM_ERR_LOG("drm plugin name lenth is not able to zero or more 256!");
201         NapiDrmError::ThrowError(env, "drm plugin name length exceeds reasonable range!", DRM_NAPI_ERR_INVALID_VAL);
202         return result;
203     }
204     if (MediaKeySystemFactoryImpl::GetInstance() == nullptr) {
205         DRM_ERR_LOG("get instance failed!");
206         NapiDrmError::ThrowError(env, "get instance failed!", DRM_NAPI_ERR_SERVICE_FATAL);
207         return result;
208     }
209     if (argc == ARGS_ONE) {
210         bool isSupported = MediaKeySystemFactoryImpl::GetInstance()->IsMediaKeySystemSupported(pluginName);
211         napi_get_boolean(env, isSupported, &result);
212         return result;
213     }
214     buffer[0] = '\0';
215     if (napi_get_value_string_utf8(env, argv[PARAM1], buffer, PATH_MAX, &length) != napi_ok) {
216         DRM_ERR_LOG("Could not able to read mimeType argument!");
217         NapiDrmError::ThrowError(env, "The param mimeType is missing or too long.", DRM_NAPI_ERR_UNKNOWN);
218         return result;
219     }
220     std::string mimeType = std::string(buffer);
221     if (argc == ARGS_TWO && mimeType.length() != 0) {
222         bool isSupported = MediaKeySystemFactoryImpl::GetInstance()->IsMediaKeySystemSupported(pluginName, mimeType);
223         napi_get_boolean(env, isSupported, &result);
224         return result;
225     }
226     buffer[0] = '\0';
227 
228     int32_t jsContentProtectionLevel = DRM_NAPI_ERR_BASE;
229     if (napi_get_value_int32(env, argv[PARAM2], &jsContentProtectionLevel) != napi_ok) {
230         DRM_ERR_LOG("Could not able to read securityLevel argument!");
231         NapiDrmError::ThrowError(env, "Could not able to read securityLevel argument.", DRM_NAPI_ERR_UNKNOWN);
232         return result;
233     }
234     ContentProtectionLevel securityLevel =
235         (ContentProtectionLevel)jsContentProtectionLevel;
236     if ((securityLevel <= ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_UNKNOWN) ||
237         (securityLevel >= ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_MAX)) {
238         DRM_ERR_LOG("ContentProtectionLevel is invalid");
239         NapiDrmError::ThrowError(env, "param ContentProtectionLevel exceeds reasonable range!",
240             DRM_NAPI_ERR_INVALID_VAL);
241         return result;
242     }
243 
244     if (argc == ARGS_THREE) {
245         bool isSupported =
246             MediaKeySystemFactoryImpl::GetInstance()->IsMediaKeySystemSupported(pluginName, mimeType, securityLevel);
247         napi_get_boolean(env, isSupported, &result);
248         return result;
249     }
250     napi_get_boolean(env, false, &result);
251     return result;
252 }
253 
mapToJsArray(napi_env env,std::map<std::string,std::string> & mediaKeySystemNames)254 static napi_value mapToJsArray(napi_env env, std::map<std::string, std::string> &mediaKeySystemNames)
255 {
256     DRM_INFO_LOG("mapToJsArray enter.");
257     napi_value jsArray;
258     int32_t i = 0;
259     if (napi_create_array_with_length(env, mediaKeySystemNames.size(), &jsArray) != napi_ok) {
260         DRM_ERR_LOG("napi_create_array_with_length failed");
261         NapiDrmError::ThrowError(env, "napi_create_array_with_length failed",
262             DRM_NAPI_ERR_UNKNOWN);
263         return nullptr;
264     }
265 
266     for (auto it = mediaKeySystemNames.begin(); it != mediaKeySystemNames.end(); it++) {
267         napi_value jsObject;
268         napi_value jsName;
269         napi_value jsValue;
270         napi_create_object(env, &jsObject);
271         napi_create_string_utf8(env, it->first.c_str(), NAPI_AUTO_LENGTH, &jsName);
272         napi_set_named_property(env, jsObject, "name", jsName);
273         napi_create_string_utf8(env, it->second.c_str(), NAPI_AUTO_LENGTH, &jsValue);
274         napi_set_named_property(env, jsObject, "uuid", jsValue);
275         napi_set_element(env, jsArray, i++, jsObject);
276     }
277     return jsArray;
278 }
279 
GetMediaKeySystems(napi_env env,napi_callback_info info)280 napi_value MediaKeySystemNapi::GetMediaKeySystems(napi_env env, napi_callback_info info)
281 {
282     DRM_INFO_LOG("GetMediaKeySystems enter");
283     napi_value result = nullptr;
284     std::map<std::string, std::string> keySystemNames;
285     napi_get_undefined(env, &result);
286     int32_t ret = MediaKeySystemFactoryImpl::GetInstance()->GetMediaKeySystems(keySystemNames);
287     if (keySystemNames.size() == 0 || ret != DRM_NAPI_ERR_OK) {
288         DRM_ERR_LOG("Plugin not exist.");
289         NapiDrmError::ThrowError(env, "GetMediaKeySystems call Failed!", DRM_NAPI_ERR_SERVICE_FATAL);
290         return result;
291     }
292     result = mapToJsArray(env, keySystemNames);
293     return result;
294 }
295 
GetMediaKeySystemUuid(napi_env env,napi_callback_info info)296 napi_value MediaKeySystemNapi::GetMediaKeySystemUuid(napi_env env, napi_callback_info info)
297 {
298     DRM_INFO_LOG("GetMediaKeySystemUuid enter");
299     napi_value result = nullptr;
300     size_t argc = ARGS_ONE;
301     napi_value argv[ARGS_ONE] = {0};
302     napi_value thisVar = nullptr;
303     napi_status status;
304     char nameStr[PATH_MAX];
305     size_t nameStrLength = 0;
306     std::string uuid;
307     napi_get_undefined(env, &result);
308 
309     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
310     NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum");
311 
312     status = napi_get_value_string_utf8(env, argv[PARAM0], nameStr, PATH_MAX, &nameStrLength);
313     if (status != napi_ok) {
314         DRM_ERR_LOG("napi_get_value_string_utf8 failed");
315         NapiDrmError::ThrowError(env, "The param configName is missing or too long.", DRM_NAPI_ERR_INVALID_VAL);
316         return result;
317     }
318     std::string name = std::string(nameStr);
319     int32_t ret = MediaKeySystemFactoryImpl::GetInstance()->GetMediaKeySystemUuid(name, uuid);
320     if (ret != DRM_NAPI_ERR_OK) {
321         DRM_ERR_LOG("GetMediaKeySystemUuid failed");
322         NapiDrmError::ThrowError(env, "GetMediaKeySystemUuid call failed", DRM_NAPI_ERR_SERVICE_FATAL);
323         return result;
324     }
325     status = napi_create_string_utf8(env, uuid.c_str(), NAPI_AUTO_LENGTH, &result);
326     if (status != napi_ok) {
327         DRM_ERR_LOG("napi_create_string_utf8 failed");
328         NapiDrmError::ThrowError(env, "napi_create_string_utf8 failed", DRM_NAPI_ERR_UNKNOWN);
329         return result;
330     }
331     return result;
332 }
333 
CreateMediaKeySession(napi_env env,napi_callback_info info)334 napi_value MediaKeySystemNapi::CreateMediaKeySession(napi_env env, napi_callback_info info)
335 {
336     DRM_INFO_LOG("CreateMediaKeySession enter.");
337     DrmTrace trace("MediaKeySystemNapi::CreateMediaKeySession");
338     napi_status status;
339     napi_value result = nullptr;
340     size_t argc = ARGS_ONE;
341     napi_value argv[ARGS_ONE] = {0};
342     napi_value thisVar = nullptr;
343     int32_t jsContentProtectionLevel = 0;
344     ContentProtectionLevel securityLevel =
345         ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_UNKNOWN;
346     sptr<MediaKeySessionImpl> keySessionImpl = nullptr;
347     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
348     napi_get_undefined(env, &result);
349     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
350     if (argc != ARGS_ZERO) {
351         status = napi_get_value_int32(env, argv[PARAM0], &jsContentProtectionLevel);
352         if (status != napi_ok) {
353             DRM_ERR_LOG("napi_get_value_int32 failed");
354             NapiDrmError::ThrowError(env, "napi_get_value_int32 failed", DRM_NAPI_ERR_UNKNOWN);
355             return result;
356         }
357         securityLevel =
358             static_cast<ContentProtectionLevel>(jsContentProtectionLevel);
359         if (securityLevel <= ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_UNKNOWN ||
360             securityLevel >= ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_MAX) {
361             NapiDrmError::ThrowError(env, "The param ContentProtectionLevel exceeds reasonable range.",
362                 DRM_NAPI_ERR_INVALID_VAL);
363             DRM_ERR_LOG("securityLevel is error!");
364             return result;
365         }
366     }
367     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
368     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
369         int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->CreateMediaKeySession(
370             (ContentProtectionLevel)securityLevel, &keySessionImpl);
371         if (ret != DRM_NAPI_ERR_OK) {
372             NapiDrmError::ThrowError(env, "CreateMediaKeySession failed.",
373                 DrmInnerErrToNapiErrAPI12(static_cast<DrmInnerErrCode>(ret)));
374             DRM_ERR_LOG("CreateMediaKeySession get failed!!!");
375             return result;
376         }
377     } else {
378         DRM_ERR_LOG("napi_unwrap call Failed!");
379         NapiDrmError::ThrowError(env, "napi_get_value_int32 failed", DRM_NAPI_ERR_UNKNOWN);
380         return result;
381     }
382     result = MediaKeySessionNapi::CreateMediaKeySession(env, keySessionImpl);
383     return result;
384 }
385 
SetConfigurationString(napi_env env,napi_callback_info info)386 napi_value MediaKeySystemNapi::SetConfigurationString(napi_env env, napi_callback_info info)
387 {
388     DRM_INFO_LOG("SetConfiguration enter.");
389     napi_value result = nullptr;
390     size_t argc = ARGS_TWO;
391     napi_value argv[ARGS_TWO] = {0};
392     napi_value thisVar = nullptr;
393     napi_status status;
394     std::string name;
395     std::string value;
396     char nameBuffer[PATH_MAX];
397     size_t nameBufferLen = 0;
398     char valueBuffer[PATH_MAX];
399     size_t valueBufferLen = 0;
400     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
401     napi_get_undefined(env, &result);
402 
403     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
404     NAPI_ASSERT(env, argc <= ARGS_TWO, "Requires 2 parameters maximum");
405 
406     status = napi_get_value_string_utf8(env, argv[PARAM0], nameBuffer, PATH_MAX, &nameBufferLen);
407     if (status != napi_ok) {
408         DRM_ERR_LOG("Could not able to read name argument!");
409         NapiDrmError::ThrowError(env, "The param configName is missing or too long", DRM_NAPI_ERR_INVALID_VAL);
410         return result;
411     }
412     name = std::string(nameBuffer);
413     status = napi_get_value_string_utf8(env, argv[PARAM1], valueBuffer, PATH_MAX, &valueBufferLen);
414     if (status != napi_ok) {
415         DRM_ERR_LOG("napi_get_value_string_utf8 failed!");
416         NapiDrmError::ThrowError(env, "The param value is missing or too long.", DRM_NAPI_ERR_INVALID_VAL);
417         return result;
418     }
419     value = std::string(valueBuffer);
420     if (value.length() == 0) {
421         DRM_ERR_LOG("String Parameter length cannot be zero!");
422         NapiDrmError::ThrowError(env, "The param value length is 0.", DRM_NAPI_ERR_INVALID_VAL);
423         return result;
424     }
425     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
426     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
427         int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->SetConfigurationString(name, value);
428         if (ret != napi_ok) {
429             DRM_ERR_LOG("SetConfigurationString failed!");
430             NapiDrmError::ThrowError(env, "SetConfigurationString failed, service error.", DRM_NAPI_ERR_SERVICE_FATAL);
431             return result;
432         }
433     } else {
434         DRM_ERR_LOG("SetConfiguration call Failed!");
435         NapiDrmError::ThrowError(env, "SetConfigurationString failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
436         return result;
437     }
438     return result;
439 }
440 
GetConfigurationString(napi_env env,napi_callback_info info)441 napi_value MediaKeySystemNapi::GetConfigurationString(napi_env env, napi_callback_info info)
442 {
443     DRM_INFO_LOG("GetConfiguration enter");
444     napi_value result = nullptr;
445     size_t argc = ARGS_ONE;
446     napi_value argv[ARGS_ONE] = {0};
447     napi_value thisVar = nullptr;
448     napi_status status;
449     char nameStr[PATH_MAX];
450     size_t nameStrLength = 0;
451     std::string value;
452     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
453     napi_get_undefined(env, &result);
454 
455     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
456     NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum");
457 
458     status = napi_get_value_string_utf8(env, argv[PARAM0], nameStr, PATH_MAX, &nameStrLength);
459     if (status != napi_ok) {
460         DRM_ERR_LOG("napi_get_value_string_utf8 failed!");
461         NapiDrmError::ThrowError(env, "The param configName is missing or too long.", DRM_NAPI_ERR_INVALID_VAL);
462         return result;
463     }
464     std::string name = std::string(nameStr);
465     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
466     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
467         int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetConfigurationString(name, value);
468         if (ret != napi_ok) {
469             DRM_ERR_LOG("GetConfigurationString failed!");
470             NapiDrmError::ThrowError(env, "GetConfigurationString failed, service error.", DRM_NAPI_ERR_SERVICE_FATAL);
471             return result;
472         }
473     } else {
474         DRM_ERR_LOG("napi_unwrap failed!");
475         NapiDrmError::ThrowError(env, "Get configuration failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
476         return result;
477     }
478 
479     napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
480     return result;
481 }
482 
SetConfigurationByteArray(napi_env env,napi_callback_info info)483 napi_value MediaKeySystemNapi::SetConfigurationByteArray(napi_env env, napi_callback_info info)
484 {
485     DRM_INFO_LOG("SetConfigurationByteArray enter.");
486     napi_value result = nullptr;
487     size_t argc = ARGS_TWO;
488     napi_value argv[ARGS_TWO] = {0};
489     napi_value thisVar = nullptr;
490     napi_status status;
491     std::string name;
492     char nameBuffer[PATH_MAX];
493     size_t nameBufferLen = 0;
494     bool isTypeArray;
495     void *valueData = nullptr;
496     size_t valueDataLen;
497     size_t offset;
498     napi_value arraybuffer = nullptr;
499     napi_typedarray_type type;
500     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
501 
502     napi_get_undefined(env, &result);
503     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
504     NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum");
505 
506     status = napi_get_value_string_utf8(env, argv[PARAM0], nameBuffer, PATH_MAX, &nameBufferLen);
507     if (status != napi_ok) {
508         DRM_ERR_LOG("Could not able to read name argument!");
509         NapiDrmError::ThrowError(env, "The param configName is missing or too long.", DRM_NAPI_ERR_INVALID_VAL);
510         return result;
511     }
512     name = std::string(nameBuffer);
513     napi_is_typedarray(env, argv[PARAM1], &isTypeArray);
514     if (!isTypeArray) {
515         DRM_ERR_LOG("Second parame is not array!");
516         NapiDrmError::ThrowError(env, "The param value type is invalid.", DRM_NAPI_ERR_INVALID_VAL);
517         return result;
518     }
519     napi_get_typedarray_info(env, argv[PARAM1], &type, &valueDataLen, &valueData, &arraybuffer, &offset);
520     if (valueData == nullptr) {
521         DRM_ERR_LOG("napi_get_typedarray_info failed!");
522         NapiDrmError::ThrowError(env, "The param value is missing or too long.", DRM_NAPI_ERR_INVALID_VAL);
523         return result;
524     }
525     uint8_t *valueDataPtr = reinterpret_cast<uint8_t *>(valueData);
526     std::vector<uint8_t> value(valueDataPtr, valueDataPtr + valueDataLen);
527     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
528     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
529         int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->SetConfigurationByteArray(name, value);
530         if (ret != napi_ok) {
531             DRM_ERR_LOG("SetConfigurationByteArray failed!");
532             NapiDrmError::ThrowError(env, "SetConfigurationByteArray failed, service error.",
533                 DRM_NAPI_ERR_SERVICE_FATAL);
534             return result;
535         }
536     } else {
537         DRM_ERR_LOG("napi_unwrap call Failed!");
538         NapiDrmError::ThrowError(env, "Set configuration failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
539         return result;
540     }
541     return result;
542 }
543 
GetConfigurationByteArray(napi_env env,napi_callback_info info)544 napi_value MediaKeySystemNapi::GetConfigurationByteArray(napi_env env, napi_callback_info info)
545 {
546     DRM_INFO_LOG("GetConfigurationByteArray enter");
547     napi_value result = nullptr;
548     size_t argc = ARGS_TWO;
549     napi_value argv[ARGS_TWO] = {0};
550     napi_value thisVar = nullptr;
551     napi_status status;
552     char nameStr[PATH_MAX];
553     size_t nameStrLength = 0;
554     std::vector<uint8_t> value;
555     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
556     napi_get_undefined(env, &result);
557 
558     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
559     NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum");
560 
561     status = napi_get_value_string_utf8(env, argv[PARAM0], nameStr, PATH_MAX, &nameStrLength);
562     if (status != napi_ok) {
563         DRM_ERR_LOG("Could not able to read name argument!");
564         NapiDrmError::ThrowError(env, "The param configName is missing or too long.", DRM_NAPI_ERR_INVALID_VAL);
565         return result;
566     }
567     std::string name = std::string(nameStr);
568     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
569     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
570         int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetConfigurationByteArray(name, value);
571         if (ret != napi_ok) {
572             DRM_ERR_LOG("GetConfigurationByteArray failed!");
573             NapiDrmError::ThrowError(env, "GetConfigurationByteArray failed, service error.",
574                 DRM_NAPI_ERR_SERVICE_FATAL);
575             return result;
576         }
577     } else {
578         DRM_ERR_LOG("napi_unwrap Failed!");
579         NapiDrmError::ThrowError(env, "GetConfigurationByteArray failed.", DRM_NAPI_ERR_UNKNOWN);
580         return result;
581     }
582     size_t valueLen = value.size();
583     NAPI_CALL(env, napi_create_array(env, &result));
584     for (size_t i = 0; i < valueLen; i++) {
585         napi_value item;
586         napi_create_int32(env, value[i], &item);
587         napi_set_element(env, result, i, item);
588     }
589     return result;
590 }
591 
GetMaxContentProtectionLevel(napi_env env,napi_callback_info info)592 napi_value MediaKeySystemNapi::GetMaxContentProtectionLevel(napi_env env, napi_callback_info info)
593 {
594     DRM_INFO_LOG("GetMaxContentProtectionLevel enter.");
595     napi_value result = nullptr;
596     size_t argc = ARGS_ONE;
597     napi_value argv[ARGS_ONE] = {0};
598     napi_value thisVar = nullptr;
599     napi_status status;
600     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
601 
602     napi_get_undefined(env, &result);
603     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
604     NAPI_ASSERT(env, argc <= ARGS_ONE, "requires one parameters maximum");
605     ContentProtectionLevel level = ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_UNKNOWN;
606     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
607     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
608         int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetMaxContentProtectionLevel(&level);
609         if (ret != napi_ok) {
610             DRM_ERR_LOG("GetCertificateStatus failed!");
611             NapiDrmError::ThrowError(env, "GetMaxContentProtectionLevel failed, service error.",
612                 DRM_NAPI_ERR_SERVICE_FATAL);
613             return result;
614         }
615     } else {
616         DRM_ERR_LOG("napi_unwrap call Failed!");
617         NapiDrmError::ThrowError(env, "GetMaxContentProtectionLevel failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
618         return result;
619     }
620 
621     NAPI_CALL(env, napi_create_int32(env, (int32_t)level, &result));
622     return result;
623 }
624 
CheckMediaKeySystemStatus(MediaKeySystemNapi * napi,std::shared_ptr<MediaKeySystemAsyncContext> context)625 bool MediaKeySystemNapi::CheckMediaKeySystemStatus(MediaKeySystemNapi *napi,
626     std::shared_ptr<MediaKeySystemAsyncContext> context)
627 {
628     DRM_NAPI_CHECK_AND_RETURN_LOG(napi != nullptr, false, "napi object is nullptr.");
629     if (napi->mediaKeySystemImpl_ == nullptr) {
630         context->SignError(DRM_NAPI_ERR_SERVICE_FATAL);
631         return false;
632     }
633     return true;
634 }
635 
CheckContextStatus(std::shared_ptr<MediaKeySystemAsyncContext> context)636 bool MediaKeySystemNapi::CheckContextStatus(std::shared_ptr<MediaKeySystemAsyncContext> context)
637 {
638     DRM_NAPI_CHECK_AND_RETURN_LOG(context != nullptr, false, "context object is nullptr.");
639     if (context->native == nullptr) {
640         context->SignError(DRM_NAPI_ERR_SERVICE_FATAL);
641         return false;
642     }
643     return true;
644 }
645 
GenerateKeySystemRequest(napi_env env,napi_callback_info info)646 napi_value MediaKeySystemNapi::GenerateKeySystemRequest(napi_env env, napi_callback_info info)
647 {
648     DRM_INFO_LOG("GenerateKeySystemRequest enter");
649     DrmTrace trace("MediaKeySystemNapi::GenerateKeySystemRequest");
650     auto context = std::make_shared<MediaKeySystemAsyncContext>();
651     if (context == nullptr) {
652         DRM_ERR_LOG("GenerateKeySystemRequest failed.");
653         NapiDrmError::ThrowError(env, "make context failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
654         return NapiParamUtils::GetUndefinedValue(env);
655     }
656 
657     context->GetCbInfo(env, info);
658 
659     auto executor = [context]() {
660         DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckContextStatus(context), "context object state is error.");
661         auto obj = reinterpret_cast<MediaKeySystemNapi *>(context->native);
662         ObjectRefMap objectGuard(obj);
663         auto *napiMediaKeySystem = objectGuard.GetPtr();
664         DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckMediaKeySystemStatus(napiMediaKeySystem, context),
665             "context object state is error.");
666         context->intValue = napiMediaKeySystem->mediaKeySystemImpl_->GenerateKeySystemRequest(
667             context->provisionRequest.data, context->provisionRequest.defaultURL);
668         if (context->intValue != 0) {
669             context->SignError(DRM_NAPI_ERR_SERVICE_FATAL);
670         }
671     };
672 
673     auto complete = [env, context](napi_value &output) {
674         NapiParamUtils::SetProvisionRequest(env, context->provisionRequest, output);
675     };
676     return NapiAsyncWork::Enqueue(env, context, "GenerateKeySystemRequest", executor, complete);
677 }
678 
ProcessKeySystemResponse(napi_env env,napi_callback_info info)679 napi_value MediaKeySystemNapi::ProcessKeySystemResponse(napi_env env, napi_callback_info info)
680 {
681     DRM_INFO_LOG("ProcessKeySystemResponse enter.");
682     int64_t beginTime = std::chrono::duration_cast<std::chrono::milliseconds>(
683         std::chrono::system_clock::now().time_since_epoch()).count();
684     DrmTrace trace("MediaKeySystemNapi::ProcessKeySystemResponse");
685     auto context = std::make_shared<MediaKeySystemAsyncContext>();
686     if (context == nullptr) {
687         DRM_ERR_LOG("ProcessKeySystemResponse failed.");
688         NapiDrmError::ThrowError(env, "make context failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
689         return NapiParamUtils::GetUndefinedValue(env);
690     }
691 
692     auto inputParser = [env, context](size_t argc, napi_value *argv) {
693         NAPI_CHECK_ARGS_RETURN_VOID(context, argc == ARGS_ONE, "invalid arguments", DRM_NAPI_ERR_INVALID_VAL);
694         context->status = NapiParamUtils::GetValueUint8Array(env, context->response, argv[PARAM0]);
695         NAPI_CHECK_STATUS_RETURN_VOID(context, "ProcessKeySystemResponse failed.", DRM_NAPI_ERR_INVALID_VAL);
696     };
697 
698     context->GetCbInfo(env, info, inputParser);
699 
700     auto executor = [context]() {
701         DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckContextStatus(context), "context object state is error.");
702         auto obj = reinterpret_cast<MediaKeySystemNapi *>(context->native);
703         ObjectRefMap objectGuard(obj);
704         auto *napiMediaKeySystem = objectGuard.GetPtr();
705         DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckMediaKeySystemStatus(napiMediaKeySystem, context),
706             "context object state is error.");
707         context->intValue = napiMediaKeySystem->mediaKeySystemImpl_->ProcessKeySystemResponse(context->response);
708         if (context->intValue != DRM_NAPI_ERR_OK) {
709             context->SignError(DRM_NAPI_ERR_SERVICE_FATAL);
710         }
711     };
712 
713     auto complete = [env](napi_value &output) { output = NapiParamUtils::GetUndefinedValue(env); };
714     ConfigParser::WriteEndEvent(0, 0, std::string("processKeySystemResponse"), beginTime);
715     return NapiAsyncWork::Enqueue(env, context, "ProcessKeySystemResponse", executor, complete);
716 }
717 
vectorToJsArray(napi_env env,std::vector<MetircKeyValue> & metrics)718 static napi_value vectorToJsArray(napi_env env, std::vector<MetircKeyValue> &metrics)
719 {
720     DRM_INFO_LOG("vectorToJsArray enter.");
721     napi_value jsArray;
722     napi_create_array_with_length(env, metrics.size(), &jsArray);
723     for (size_t i = 0; i < metrics.size(); i++) {
724         napi_value jsObject;
725         napi_value jsName;
726         napi_value jsValue;
727         napi_create_object(env, &jsObject);
728         napi_create_string_utf8(env, metrics[i].name.c_str(), NAPI_AUTO_LENGTH, &jsName);
729         napi_set_named_property(env, jsObject, "name", jsName);
730         napi_create_string_utf8(env, metrics[i].value.c_str(), NAPI_AUTO_LENGTH, &jsValue);
731         napi_set_named_property(env, jsObject, "value", jsValue);
732 
733         napi_set_element(env, jsArray, i, jsObject);
734     }
735     return jsArray;
736 }
737 
GetStatistics(napi_env env,napi_callback_info info)738 napi_value MediaKeySystemNapi::GetStatistics(napi_env env, napi_callback_info info)
739 {
740     DRM_INFO_LOG("GetStatistics enter.");
741     napi_value result = nullptr;
742     size_t argc = ARGS_ZERO;
743     napi_value argv[ARGS_ZERO];
744     napi_value thisVar = nullptr;
745     napi_status status;
746     std::vector<MetircKeyValue> metrics;
747     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
748     napi_get_undefined(env, &result);
749 
750     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
751     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
752     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
753         int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetStatistics(metrics);
754         if (ret != napi_ok) {
755             DRM_ERR_LOG("GetStatistics failed!");
756             NapiDrmError::ThrowError(env, "Get statistics failed, service error.", DRM_NAPI_ERR_SERVICE_FATAL);
757             return result;
758         }
759     } else {
760         DRM_ERR_LOG("napi_unwrap Failed!");
761         NapiDrmError::ThrowError(env, "GetStatistics failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
762         return result;
763     }
764     result = vectorToJsArray(env, metrics);
765     return result;
766 }
767 
GetCertificateStatus(napi_env env,napi_callback_info info)768 napi_value MediaKeySystemNapi::GetCertificateStatus(napi_env env, napi_callback_info info)
769 {
770     DrmTrace trace("MediaKeySystemNapi::GetCertificateStatus");
771     DRM_INFO_LOG("GetCertificateStatus enter.");
772     napi_value result = nullptr;
773     size_t argc = ARGS_ZERO;
774     napi_value argv[ARGS_ZERO];
775     napi_value thisVar = nullptr;
776     napi_status status;
777     CertificateStatus certStatus;
778     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
779 
780     napi_get_undefined(env, &result);
781     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
782     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
783     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
784         int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetCertificateStatus(&certStatus);
785         if (ret != napi_ok) {
786             DRM_ERR_LOG("GetCertificateStatus failed!");
787             NapiDrmError::ThrowError(env, "GetCertificateStatus failed, service error.", DRM_NAPI_ERR_SERVICE_FATAL);
788             return result;
789         }
790     } else {
791         DRM_ERR_LOG("napi_unwrap Failed!");
792         NapiDrmError::ThrowError(env, "GetCertificateStatus failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
793         return result;
794     }
795     NAPI_CALL(env, napi_create_int32(env, (int32_t)certStatus, &result));
796     return result;
797 }
798 
vectorToJs2DArray(napi_env env,std::vector<std::vector<uint8_t>> vec,napi_value result)799 static napi_value vectorToJs2DArray(napi_env env, std::vector<std::vector<uint8_t>> vec, napi_value result)
800 {
801     DRM_INFO_LOG("vectorToJs2DArray enter.");
802     napi_value outArray;
803     napi_value inArray;
804     napi_status status = napi_create_array(env, &outArray);
805     if (status != napi_ok) {
806         DRM_ERR_LOG("napi_create_array failed!");
807         NapiDrmError::ThrowError(env, "napi_create_array failed.", DRM_NAPI_ERR_UNKNOWN);
808         return result;
809     }
810 
811     for (size_t i = 0; i < vec.size(); i++) {
812         status = napi_create_array(env, &inArray);
813         if (status != napi_ok) {
814             DRM_ERR_LOG("napi_create_array failed!");
815             NapiDrmError::ThrowError(env, "napi_create_array failed.", DRM_NAPI_ERR_UNKNOWN);
816             return result;
817         }
818 
819         for (size_t j = 0; j < vec[i].size(); j++) {
820             napi_value elem;
821             status = napi_create_uint32(env, vec[i][j], &elem);
822             if (status != napi_ok) {
823                 DRM_ERR_LOG("napi_create_uint32 failed!");
824                 NapiDrmError::ThrowError(env, "napi_create_uint32 failed.", DRM_NAPI_ERR_UNKNOWN);
825                 return result;
826             }
827             status = napi_set_element(env, inArray, j, elem);
828             if (status != napi_ok) {
829                 DRM_ERR_LOG("napi_set_element failed!");
830                 NapiDrmError::ThrowError(env, "napi_set_element failed.", DRM_NAPI_ERR_UNKNOWN);
831                 return result;
832             }
833         }
834         status = napi_set_element(env, outArray, i, inArray);
835         if (status != napi_ok) {
836             DRM_ERR_LOG("napi_set_element failed!");
837             NapiDrmError::ThrowError(env, "napi_set_element failed.", DRM_NAPI_ERR_UNKNOWN);
838             return result;
839         }
840     }
841     return outArray;
842 }
843 
GetOfflineMediaKeyIds(napi_env env,napi_callback_info info)844 napi_value MediaKeySystemNapi::GetOfflineMediaKeyIds(napi_env env, napi_callback_info info)
845 {
846     DRM_INFO_LOG("GetOfflineMediaKeyIds enter.");
847     napi_value result = nullptr;
848     size_t argc = ARGS_ZERO;
849     napi_value argv[ARGS_ZERO];
850     napi_value thisVar = nullptr;
851     napi_status status;
852     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
853 
854     napi_get_undefined(env, &result);
855     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
856     NAPI_ASSERT(env, argc >= ARGS_ZERO, "requires 0 parameters maximum");
857     std::vector<std::vector<uint8_t>> licenseIds;
858     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
859     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
860         int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetOfflineMediaKeyIds(licenseIds);
861         if (ret != napi_ok) {
862             DRM_ERR_LOG("napi GetOfflineMediaKeyIds failed!");
863             NapiDrmError::ThrowError(env, "GetOfflineMediaKeyIds failed, service error.", DRM_NAPI_ERR_SERVICE_FATAL);
864             return result;
865         }
866     } else {
867         DRM_ERR_LOG("napi_unwrap call Failed!");
868         NapiDrmError::ThrowError(env, "GetOfflineMediaKeyIds failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
869         return result;
870     }
871 
872     result = vectorToJs2DArray(env, licenseIds, result);
873     return result;
874 }
875 
GetOfflineMediaKeyStatus(napi_env env,napi_callback_info info)876 napi_value MediaKeySystemNapi::GetOfflineMediaKeyStatus(napi_env env, napi_callback_info info)
877 {
878     DRM_INFO_LOG("GetOfflineMediaKeyStatus enter");
879     napi_value result = nullptr;
880     size_t argc = ARGS_ONE;
881     napi_value argv[ARGS_ONE] = {0};
882     napi_value thisVar = nullptr;
883     napi_status status;
884     void *licenseId = nullptr;
885     size_t licenseIdLen;
886     size_t offset;
887     napi_value arraybuffer = nullptr;
888     napi_typedarray_type type;
889     bool isTypeArray;
890     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
891 
892     napi_get_undefined(env, &result);
893     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
894     NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum");
895     napi_is_typedarray(env, argv[PARAM0], &isTypeArray);
896     if (!isTypeArray) {
897         DRM_ERR_LOG("First parame is not array!");
898         NapiDrmError::ThrowError(env, "The param mediaKeyId type is not array.", DRM_NAPI_ERR_INVALID_VAL);
899         return result;
900     }
901     napi_get_typedarray_info(env, argv[PARAM0], &type, &licenseIdLen, &licenseId, &arraybuffer, &offset);
902     if (licenseId == nullptr) {
903         DRM_ERR_LOG("napi_get_typedarray_info failed!");
904         NapiDrmError::ThrowError(env, "The param mediaKeyId is invalid.", DRM_NAPI_ERR_INVALID_VAL);
905         return result;
906     }
907     uint8_t *licenseIdPtr = reinterpret_cast<uint8_t *>(licenseId);
908     std::vector<uint8_t> licenseIdVec(licenseIdPtr, licenseIdPtr + licenseIdLen);
909     OfflineMediaKeyStatus offlineMediaKeyStatus =
910         OfflineMediaKeyStatus::OFFLINELICENSESTATUS_UNKNOWN;
911     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
912     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
913         int32_t ret =
914             mediaKeySystemNapi->mediaKeySystemImpl_->GetOfflineMediaKeyStatus(licenseIdVec, offlineMediaKeyStatus);
915         if (ret != napi_ok) {
916             DRM_ERR_LOG("GetOfflineMediaKeyStatus failed!");
917             NapiDrmError::ThrowError(env, "GetOfflineMediaKeyStatus failed, service error.",
918                 DRM_NAPI_ERR_SERVICE_FATAL);
919             return result;
920         }
921     } else {
922         DRM_ERR_LOG("napi_unwrap call Failed!");
923         NapiDrmError::ThrowError(env, "GetOfflineMediaKeyStatus failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
924         return result;
925     }
926 
927     NAPI_CALL(env, napi_create_int32(env, (int32_t)offlineMediaKeyStatus, &result));
928     return result;
929 }
930 
ClearOfflineMediaKeys(napi_env env,napi_callback_info info)931 napi_value MediaKeySystemNapi::ClearOfflineMediaKeys(napi_env env, napi_callback_info info)
932 {
933     DRM_INFO_LOG("ClearOfflineMediaKeys enter.");
934     napi_value result = nullptr;
935     size_t argc = ARGS_ONE;
936     napi_value argv[ARGS_ONE] = {0};
937     napi_value thisVar = nullptr;
938     napi_status status;
939     bool isTypeArray;
940     void *licenseId = nullptr;
941     size_t licenseIdLen;
942     size_t offset;
943     napi_value arraybuffer = nullptr;
944     napi_typedarray_type type;
945     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
946 
947     napi_get_undefined(env, &result);
948     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
949     NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 2 parameters maximum");
950     napi_is_typedarray(env, argv[PARAM0], &isTypeArray);
951     if (!isTypeArray) {
952         DRM_ERR_LOG("argv[PARAM0] is not array!");
953         NapiDrmError::ThrowError(env, "The param mediaKeyId is not array.", DRM_NAPI_ERR_INVALID_VAL);
954         return result;
955     }
956     napi_get_typedarray_info(env, argv[PARAM0], &type, &licenseIdLen, &licenseId, &arraybuffer, &offset);
957     if (licenseId == nullptr) {
958         DRM_ERR_LOG("napi_get_typedarray_info failed!");
959         NapiDrmError::ThrowError(env, "ClearOfflineMediaKeys failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
960         return result;
961     }
962     uint8_t *licenseIdPtr = reinterpret_cast<uint8_t *>(licenseId);
963     std::vector<uint8_t> licenseIdVec(licenseIdPtr, licenseIdPtr + licenseIdLen);
964     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
965     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
966         int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->ClearOfflineMediaKeys(licenseIdVec);
967         if (ret != napi_ok) {
968             DRM_ERR_LOG("ClearOfflineMediaKeys failed!");
969             NapiDrmError::ThrowError(env, "ClearOfflineMediaKeys failed, service error.", DRM_NAPI_ERR_SERVICE_FATAL);
970             return result;
971         }
972     } else {
973         DRM_ERR_LOG("ClearOfflineMediaKeys call Failed!");
974         NapiDrmError::ThrowError(env, "ClearOfflineMediaKeys failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
975         return result;
976     }
977 
978     return result;
979 }
980 
Destroy(napi_env env,napi_callback_info info)981 napi_value MediaKeySystemNapi::Destroy(napi_env env, napi_callback_info info)
982 {
983     DRM_INFO_LOG("Release enter.");
984     int32_t currentPid = IPCSkeleton::GetCallingPid();
985     DRM_DEBUG_LOG("GetCallingPID: %{public}d", currentPid);
986 
987     napi_status status;
988     napi_value result = nullptr;
989     size_t argc = ARGS_ZERO;
990     napi_value argv[ARGS_ZERO];
991     napi_value thisVar = nullptr;
992     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
993 
994     napi_get_undefined(env, &result);
995     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
996     napi_get_undefined(env, &result);
997     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
998     if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
999         int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->Release();
1000         if (ret != napi_ok) {
1001             DRM_ERR_LOG("GetCertificateStatus failed!");
1002             NapiDrmError::ThrowError(env, "Destroy failed, service error.", DRM_NAPI_ERR_SERVICE_FATAL);
1003             return result;
1004         }
1005     } else {
1006         DRM_ERR_LOG("napi_unwrap Failed!");
1007         NapiDrmError::ThrowError(env, "Destroy failed.", DRM_NAPI_ERR_UNKNOWN);
1008         return result;
1009     }
1010     return result;
1011 }
1012 
SaveEventCallbackReferrence(const std::string eventType,std::shared_ptr<AutoRef> callbackPair)1013 void MediaKeySystemNapi::SaveEventCallbackReferrence(const std::string eventType, std::shared_ptr<AutoRef> callbackPair)
1014 {
1015     DRM_INFO_LOG("SaveEventCallbackReferrence");
1016     std::lock_guard<std::mutex> lock(mutex_);
1017     if (mediaKeySystemCallbackNapi_ != nullptr) {
1018         mediaKeySystemCallbackNapi_->SetCallbackReference(eventType, callbackPair);
1019     } else {
1020         DRM_ERR_LOG("SaveEventCallbackReferrence failed.");
1021     }
1022 }
1023 
ClearEventCallbackReferrence(const std::string eventType)1024 void MediaKeySystemNapi::ClearEventCallbackReferrence(const std::string eventType)
1025 {
1026     DRM_INFO_LOG("ClearEventCallbackReference");
1027     if (mediaKeySystemCallbackNapi_ != nullptr) {
1028         mediaKeySystemCallbackNapi_->ClearCallbackReference(eventType);
1029     } else {
1030         DRM_ERR_LOG("ClearEventCallbackReference failed.");
1031     }
1032 }
1033 
SetEventCallback(napi_env env,napi_callback_info info)1034 napi_value MediaKeySystemNapi::SetEventCallback(napi_env env, napi_callback_info info)
1035 {
1036     DRM_INFO_LOG("SetEventCallback");
1037     napi_value result = nullptr;
1038     napi_get_undefined(env, &result);
1039     size_t length = 0;
1040     size_t argc = ARGS_TWO;
1041     napi_value thisVar = nullptr;
1042     napi_value argv[ARGS_TWO] = { nullptr };
1043     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1044     NAPI_ASSERT(env, argc == ARGS_TWO, "only requires 2 parameters");
1045     if (thisVar == nullptr || argv[PARAM0] == nullptr || argv[PARAM1] == nullptr) {
1046         NapiDrmError::ThrowError(env, "Mandatory parameters are left unspecified.", DRM_NAPI_ERR_INVALID_VAL);
1047         DRM_ERR_LOG("Failed to retrieve arguments in SetEventCallback!");
1048         return result;
1049     }
1050     napi_valuetype valueType = napi_undefined;
1051     if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string ||
1052         napi_typeof(env, argv[PARAM1], &valueType) != napi_ok || valueType != napi_function) {
1053         NapiDrmError::ThrowError(env, "Mandatory parameter type is invalid.", DRM_NAPI_ERR_INVALID_VAL);
1054         return result;
1055     }
1056 
1057     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
1058     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
1059     if (status == napi_ok && mediaKeySystemNapi != nullptr) {
1060         char buffer[PATH_MAX];
1061         napi_get_value_string_utf8(env, argv[PARAM0], buffer, PATH_MAX, &length);
1062         std::string eventType = std::string(buffer);
1063         napi_ref callbackRef;
1064         napi_create_reference(env, argv[PARAM1], 1, &callbackRef);
1065         DRM_INFO_LOG("SetEventCallback event is %{public}s", eventType.c_str());
1066 
1067         std::shared_ptr<AutoRef> callbackPair = std::make_shared<AutoRef>(env, callbackRef);
1068         mediaKeySystemNapi->SaveEventCallbackReferrence(eventType, callbackPair);
1069         DRM_INFO_LOG("SetEventCallback out");
1070     } else {
1071         NapiDrmError::ThrowError(env, "SetEventCallback failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
1072         DRM_ERR_LOG("SetEventCallback failed!");
1073     }
1074     return result;
1075 }
1076 
UnsetEventCallback(napi_env env,napi_callback_info info)1077 napi_value MediaKeySystemNapi::UnsetEventCallback(napi_env env, napi_callback_info info)
1078 {
1079     DRM_INFO_LOG("UnsetEventCallback");
1080     napi_value result = nullptr;
1081     napi_get_undefined(env, &result);
1082     napi_value thisVar = nullptr;
1083     napi_value argv[ARGS_ONE] = { nullptr };
1084     size_t argc = 1;
1085     DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1086     NAPI_ASSERT(env, argc == ARGS_ONE, "only requires 1 parameters");
1087     if (thisVar == nullptr || argv[PARAM0] == nullptr) {
1088         DRM_ERR_LOG("Failed to retrieve arguments in UnsetEventCallback!");
1089         NapiDrmError::ThrowError(env, "The param callback type is missing.", DRM_NAPI_ERR_INVALID_VAL);
1090         return result;
1091     }
1092     napi_valuetype valueType = napi_undefined;
1093     if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string) {
1094         DRM_ERR_LOG("Failed to retrieve reasonable arguments in UnsetEventCallback!");
1095         NapiDrmError::ThrowError(env, "The param callback type is not string.", DRM_NAPI_ERR_INVALID_VAL);
1096         return result;
1097     }
1098 
1099     MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
1100     char buffer[PATH_MAX];
1101     size_t length = 0;
1102     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
1103     if (status == napi_ok && mediaKeySystemNapi != nullptr) {
1104         napi_get_value_string_utf8(env, argv[PARAM0], buffer, PATH_MAX, &length);
1105         std::string eventType = std::string(buffer);
1106         mediaKeySystemNapi->ClearEventCallbackReferrence(eventType);
1107         DRM_INFO_LOG("UnsetEventCallback out");
1108     } else {
1109         NapiDrmError::ThrowError(env, "UnsetEventCallback failed, unknown error.", DRM_NAPI_ERR_UNKNOWN);
1110         DRM_ERR_LOG("UnsetEventCallback failed!");
1111     }
1112     return result;
1113 }
1114 } // namespace DrmStandard
1115 } // namespace OHOS