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