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.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_INVALID_PARAM);
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_OK) {
156 NapiDrmError::ThrowError(env, "create MediaKeySystem failed.", ret);
157 DRM_ERR_LOG("CreateMediaKeySystem failed!");
158 return result;
159 }
160 status = napi_new_instance(env, ctor, 0, nullptr, &result);
161 MediaKeySystemNapi::sMediaKeySystemImpl_ = nullptr;
162 if (status == napi_ok) {
163 return result;
164 } else {
165 DRM_ERR_LOG("New instance could not be obtained");
166 }
167 }
168 NapiDrmError::ThrowError(env, "create MediaKeySystem failed, unknown error.", DRM_UNKNOWN_ERROR);
169 napi_get_undefined(env, &result);
170 return result;
171 }
172
MediaKeySystemNapiDestructor(napi_env env,void * nativeObject,void * finalize)173 void MediaKeySystemNapi::MediaKeySystemNapiDestructor(napi_env env, void *nativeObject, void *finalize)
174 {
175 DrmTrace trace("MediaKeySystemNapi::MediaKeySystemNapiDestructor");
176 DRM_INFO_LOG("MediaKeySystemNapiDestructor enter.");
177 MediaKeySystemNapi *mediaKeySystemNapi = reinterpret_cast<MediaKeySystemNapi *>(nativeObject);
178 ObjectRefMap<MediaKeySystemNapi>::DecreaseRef(mediaKeySystemNapi);
179 }
180
IsMediaKeySystemSupported(napi_env env,napi_callback_info info)181 napi_value MediaKeySystemNapi::IsMediaKeySystemSupported(napi_env env, napi_callback_info info)
182 {
183 DRM_INFO_LOG("IsMediaKeySystemSupported enter.");
184 napi_value result = nullptr;
185 size_t argc = ARGS_THREE;
186 napi_value argv[ARGS_THREE] = {0, 0, 0};
187 napi_value thisVar = nullptr;
188 napi_get_undefined(env, &result);
189 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
190 char buffer[PATH_MAX];
191 size_t length = 0;
192 if (napi_get_value_string_utf8(env, argv[PARAM0], buffer, PATH_MAX, &length) != napi_ok) {
193 DRM_ERR_LOG("Could not able to read drm plugin name argument!");
194 NapiDrmError::ThrowError(env, "Could not able to read drm plugin name argument!", DRM_UNKNOWN_ERROR);
195 return result;
196 }
197 std::string pluginName = std::string(buffer);
198 if (pluginName.length() == 0 || pluginName.length() > MAX_STRING_SIZE) {
199 DRM_ERR_LOG("drm plugin name lenth is not able to zero or more 256!");
200 NapiDrmError::ThrowError(env, "drm plugin name length exceeds reasonable range!", DRM_INVALID_PARAM);
201 return result;
202 }
203 if (MediaKeySystemFactoryImpl::GetInstance() == nullptr) {
204 DRM_ERR_LOG("get instance failed!");
205 NapiDrmError::ThrowError(env, "get instance failed!", DRM_SERVICE_FATAL_ERROR);
206 return result;
207 }
208 if (argc == ARGS_ONE) {
209 bool isSurpportted = MediaKeySystemFactoryImpl::GetInstance()->IsMediaKeySystemSupported(pluginName);
210 napi_get_boolean(env, isSurpportted, &result);
211 return result;
212 }
213 buffer[0] = '\0';
214 if (napi_get_value_string_utf8(env, argv[PARAM1], buffer, PATH_MAX, &length) != napi_ok) {
215 DRM_ERR_LOG("Could not able to read mimeType argument!");
216 NapiDrmError::ThrowError(env, "The param mimeType is missing or too long.", DRM_UNKNOWN_ERROR);
217 return result;
218 }
219 std::string mimeType = std::string(buffer);
220 if (argc == ARGS_TWO && mimeType.length() != 0) {
221 bool isSurpportted = MediaKeySystemFactoryImpl::GetInstance()->IsMediaKeySystemSupported(pluginName, mimeType);
222 napi_get_boolean(env, isSurpportted, &result);
223 return result;
224 }
225 buffer[0] = '\0';
226
227 int32_t jsContentProtectionLevel = DRM_ERROR;
228 if (napi_get_value_int32(env, argv[PARAM2], &jsContentProtectionLevel) != napi_ok) {
229 DRM_ERR_LOG("Could not able to read securityLevel argument!");
230 NapiDrmError::ThrowError(env, "Could not able to read securityLevel argument.", DRM_UNKNOWN_ERROR);
231 return result;
232 }
233 IMediaKeySessionService::ContentProtectionLevel securityLevel =
234 (IMediaKeySessionService::ContentProtectionLevel)jsContentProtectionLevel;
235 if ((securityLevel <= IMediaKeySessionService::CONTENT_PROTECTION_LEVEL_UNKNOWN) ||
236 (securityLevel >= IMediaKeySessionService::CONTENT_PROTECTION_LEVEL_MAX)) {
237 DRM_ERR_LOG("ContentProtectionLevel is invalid");
238 NapiDrmError::ThrowError(env, "param ContentProtectionLevel exceeds reasonable range!", DRM_INVALID_PARAM);
239 return result;
240 }
241
242 if (argc == ARGS_THREE) {
243 bool isSurpportted =
244 MediaKeySystemFactoryImpl::GetInstance()->IsMediaKeySystemSupported(pluginName, mimeType, securityLevel);
245 napi_get_boolean(env, isSurpportted, &result);
246 return result;
247 }
248 napi_get_boolean(env, false, &result);
249 return result;
250 }
251
mapToJsArray(napi_env env,std::map<std::string,std::string> & mediaKeySystemNames)252 static napi_value mapToJsArray(napi_env env, std::map<std::string, std::string> &mediaKeySystemNames)
253 {
254 DRM_INFO_LOG("mapToJsArray enter.");
255 napi_value jsArray;
256 int32_t i = 0;
257 if (napi_create_array_with_length(env, mediaKeySystemNames.size(), &jsArray) != napi_ok) {
258 DRM_ERR_LOG("napi_create_array_with_length failed");
259 NapiDrmError::ThrowError(env, "napi_create_array_with_length failed",
260 DRM_UNKNOWN_ERROR);
261 return nullptr;
262 }
263
264 for (auto it = mediaKeySystemNames.begin(); it != mediaKeySystemNames.end(); it++) {
265 napi_value jsObject;
266 napi_value jsName;
267 napi_value jsValue;
268 napi_create_object(env, &jsObject);
269 napi_create_string_utf8(env, it->first.c_str(), NAPI_AUTO_LENGTH, &jsName);
270 napi_set_named_property(env, jsObject, "name", jsName);
271 napi_create_string_utf8(env, it->second.c_str(), NAPI_AUTO_LENGTH, &jsValue);
272 napi_set_named_property(env, jsObject, "uuid", jsValue);
273 napi_set_element(env, jsArray, i++, jsObject);
274 }
275 return jsArray;
276 }
277
GetMediaKeySystems(napi_env env,napi_callback_info info)278 napi_value MediaKeySystemNapi::GetMediaKeySystems(napi_env env, napi_callback_info info)
279 {
280 DRM_INFO_LOG("GetMediaKeySystems enter");
281 napi_value result = nullptr;
282 std::map<std::string, std::string> keySystemNames;
283 napi_get_undefined(env, &result);
284 int32_t ret = MediaKeySystemFactoryImpl::GetInstance()->GetMediaKeySystems(keySystemNames);
285 if (keySystemNames.size() == 0 || ret != DRM_OK) {
286 DRM_ERR_LOG("Plugin not exist.");
287 NapiDrmError::ThrowError(env, "GetMediaKeySystems call Failed!", DRM_SERVICE_FATAL_ERROR);
288 return result;
289 }
290 result = mapToJsArray(env, keySystemNames);
291 return result;
292 }
293
GetMediaKeySystemUuid(napi_env env,napi_callback_info info)294 napi_value MediaKeySystemNapi::GetMediaKeySystemUuid(napi_env env, napi_callback_info info)
295 {
296 DRM_INFO_LOG("GetMediaKeySystemUuid enter");
297 napi_value result = nullptr;
298 size_t argc = ARGS_ONE;
299 napi_value argv[ARGS_ONE] = {0};
300 napi_value thisVar = nullptr;
301 napi_status status;
302 char nameStr[PATH_MAX];
303 size_t nameStrLength = 0;
304 std::string uuid;
305 napi_get_undefined(env, &result);
306
307 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
308 NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum");
309
310 status = napi_get_value_string_utf8(env, argv[PARAM0], nameStr, PATH_MAX, &nameStrLength);
311 if (status != napi_ok) {
312 DRM_ERR_LOG("napi_get_value_string_utf8 failed");
313 NapiDrmError::ThrowError(env, "The param configName is missing or too long.", DRM_INVALID_PARAM);
314 return result;
315 }
316 std::string name = std::string(nameStr);
317 int32_t ret = MediaKeySystemFactoryImpl::GetInstance()->GetMediaKeySystemUuid(name, uuid);
318 if (ret != DRM_OK) {
319 DRM_ERR_LOG("GetMediaKeySystemUuid failed");
320 NapiDrmError::ThrowError(env, "GetMediaKeySystemUuid call failed", DRM_SERVICE_FATAL_ERROR);
321 return result;
322 }
323 status = napi_create_string_utf8(env, uuid.c_str(), NAPI_AUTO_LENGTH, &result);
324 if (status != napi_ok) {
325 DRM_ERR_LOG("napi_create_string_utf8 failed");
326 NapiDrmError::ThrowError(env, "napi_create_string_utf8 failed", DRM_UNKNOWN_ERROR);
327 return result;
328 }
329 return result;
330 }
331
CreateMediaKeySession(napi_env env,napi_callback_info info)332 napi_value MediaKeySystemNapi::CreateMediaKeySession(napi_env env, napi_callback_info info)
333 {
334 DRM_INFO_LOG("CreateMediaKeySession enter.");
335 DrmTrace trace("MediaKeySystemNapi::CreateMediaKeySession");
336 napi_status status;
337 napi_value result = nullptr;
338 size_t argc = ARGS_ONE;
339 napi_value argv[ARGS_ONE] = {0};
340 napi_value thisVar = nullptr;
341 int32_t jsContentProtectionLevel = 0;
342 IMediaKeySessionService::ContentProtectionLevel securityLevel =
343 IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_UNKNOWN;
344 sptr<MediaKeySessionImpl> keySessionImpl = nullptr;
345 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
346 napi_get_undefined(env, &result);
347 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
348 if (argc != ARGS_ZERO) {
349 status = napi_get_value_int32(env, argv[PARAM0], &jsContentProtectionLevel);
350 if (status != napi_ok) {
351 DRM_ERR_LOG("napi_get_value_int32 failed");
352 NapiDrmError::ThrowError(env, "napi_get_value_int32 failed", DRM_UNKNOWN_ERROR);
353 return result;
354 }
355 securityLevel =
356 static_cast<IMediaKeySessionService::ContentProtectionLevel>(jsContentProtectionLevel);
357 if (securityLevel <= IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_UNKNOWN ||
358 securityLevel >= IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_MAX) {
359 NapiDrmError::ThrowError(env, "The param ContentProtectionLevel exceeds reasonable range.",
360 DRM_INVALID_PARAM);
361 DRM_ERR_LOG("securityLevel is error!");
362 return result;
363 }
364 }
365 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
366 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
367 int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->CreateMediaKeySession(
368 (IMediaKeySessionService::ContentProtectionLevel)securityLevel, &keySessionImpl);
369 if (ret != DRM_OK) {
370 NapiDrmError::ThrowError(env, "CreateMediaKeySession failed.", ret);
371 DRM_ERR_LOG("CreateMediaKeySession get failed!!!");
372 return result;
373 }
374 } else {
375 DRM_ERR_LOG("napi_unwrap call Failed!");
376 NapiDrmError::ThrowError(env, "napi_get_value_int32 failed", DRM_UNKNOWN_ERROR);
377 return result;
378 }
379 result = MediaKeySessionNapi::CreateMediaKeySession(env, keySessionImpl);
380 return result;
381 }
382
SetConfigurationString(napi_env env,napi_callback_info info)383 napi_value MediaKeySystemNapi::SetConfigurationString(napi_env env, napi_callback_info info)
384 {
385 DRM_INFO_LOG("SetConfiguration enter.");
386 napi_value result = nullptr;
387 size_t argc = ARGS_TWO;
388 napi_value argv[ARGS_TWO] = {0};
389 napi_value thisVar = nullptr;
390 napi_status status;
391 std::string name;
392 std::string value;
393 char nameBuffer[PATH_MAX];
394 size_t nameBufferLen = 0;
395 char valueBuffer[PATH_MAX];
396 size_t valueBufferLen = 0;
397 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
398 napi_get_undefined(env, &result);
399
400 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
401 NAPI_ASSERT(env, argc <= ARGS_TWO, "Requires 2 parameters maximum");
402
403 status = napi_get_value_string_utf8(env, argv[PARAM0], nameBuffer, PATH_MAX, &nameBufferLen);
404 if (status != napi_ok) {
405 DRM_ERR_LOG("Could not able to read name argument!");
406 NapiDrmError::ThrowError(env, "The param configName is missing or too long", DRM_INVALID_PARAM);
407 return result;
408 }
409 name = std::string(nameBuffer);
410 status = napi_get_value_string_utf8(env, argv[PARAM1], valueBuffer, PATH_MAX, &valueBufferLen);
411 if (status != napi_ok) {
412 DRM_ERR_LOG("napi_get_value_string_utf8 failed!");
413 NapiDrmError::ThrowError(env, "The param value is missing or too long.", DRM_INVALID_PARAM);
414 return result;
415 }
416 value = std::string(valueBuffer);
417 if (value.length() == 0) {
418 DRM_ERR_LOG("String Parameter length cannot be zero!");
419 NapiDrmError::ThrowError(env, "The param value length is 0.", DRM_INVALID_PARAM);
420 return result;
421 }
422 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
423 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
424 int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->SetConfigurationString(name, value);
425 if (ret != napi_ok) {
426 DRM_ERR_LOG("SetConfigurationString failed!");
427 NapiDrmError::ThrowError(env, "SetConfigurationString failed, service error.", DRM_SERVICE_FATAL_ERROR);
428 return result;
429 }
430 } else {
431 DRM_ERR_LOG("SetConfiguration call Failed!");
432 NapiDrmError::ThrowError(env, "SetConfigurationString failed, unknown error.", DRM_UNKNOWN_ERROR);
433 return result;
434 }
435 return result;
436 }
437
GetConfigurationString(napi_env env,napi_callback_info info)438 napi_value MediaKeySystemNapi::GetConfigurationString(napi_env env, napi_callback_info info)
439 {
440 DRM_INFO_LOG("GetConfiguration enter");
441 napi_value result = nullptr;
442 size_t argc = ARGS_ONE;
443 napi_value argv[ARGS_ONE] = {0};
444 napi_value thisVar = nullptr;
445 napi_status status;
446 char nameStr[PATH_MAX];
447 size_t nameStrLength = 0;
448 std::string value;
449 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
450 napi_get_undefined(env, &result);
451
452 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
453 NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum");
454
455 status = napi_get_value_string_utf8(env, argv[PARAM0], nameStr, PATH_MAX, &nameStrLength);
456 if (status != napi_ok) {
457 DRM_ERR_LOG("napi_get_value_string_utf8 failed!");
458 NapiDrmError::ThrowError(env, "The param configName is missing or too long.", DRM_INVALID_PARAM);
459 return result;
460 }
461 std::string name = std::string(nameStr);
462 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
463 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
464 int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetConfigurationString(name, value);
465 if (ret != napi_ok) {
466 DRM_ERR_LOG("GetConfigurationString failed!");
467 NapiDrmError::ThrowError(env, "GetConfigurationString failed, service error.", DRM_SERVICE_FATAL_ERROR);
468 return result;
469 }
470 } else {
471 DRM_ERR_LOG("napi_unwrap failed!");
472 NapiDrmError::ThrowError(env, "Get configuration failed, unknown error.", DRM_UNKNOWN_ERROR);
473 return result;
474 }
475
476 napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
477 return result;
478 }
479
SetConfigurationByteArray(napi_env env,napi_callback_info info)480 napi_value MediaKeySystemNapi::SetConfigurationByteArray(napi_env env, napi_callback_info info)
481 {
482 DRM_INFO_LOG("SetConfigurationByteArray enter.");
483 napi_value result = nullptr;
484 size_t argc = ARGS_TWO;
485 napi_value argv[ARGS_TWO] = {0};
486 napi_value thisVar = nullptr;
487 napi_status status;
488 std::string name;
489 char nameBuffer[PATH_MAX];
490 size_t nameBufferLen = 0;
491 bool isTypeArray;
492 void *valueData = nullptr;
493 size_t valueDataLen;
494 size_t offset;
495 napi_value arraybuffer = nullptr;
496 napi_typedarray_type type;
497 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
498
499 napi_get_undefined(env, &result);
500 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
501 NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum");
502
503 status = napi_get_value_string_utf8(env, argv[PARAM0], nameBuffer, PATH_MAX, &nameBufferLen);
504 if (status != napi_ok) {
505 DRM_ERR_LOG("Could not able to read name argument!");
506 NapiDrmError::ThrowError(env, "The param configName is missing or too long.", DRM_INVALID_PARAM);
507 return result;
508 }
509 name = std::string(nameBuffer);
510 napi_is_typedarray(env, argv[PARAM1], &isTypeArray);
511 if (!isTypeArray) {
512 DRM_ERR_LOG("Second parame is not array!");
513 NapiDrmError::ThrowError(env, "The param value type is invalid.", DRM_INVALID_PARAM);
514 return result;
515 }
516 napi_get_typedarray_info(env, argv[PARAM1], &type, &valueDataLen, &valueData, &arraybuffer, &offset);
517 if (valueData == nullptr) {
518 DRM_ERR_LOG("napi_get_typedarray_info failed!");
519 NapiDrmError::ThrowError(env, "The param value is missing or too long.", DRM_INVALID_PARAM);
520 return result;
521 }
522 uint8_t *valueDataPtr = reinterpret_cast<uint8_t *>(valueData);
523 std::vector<uint8_t> value(valueDataPtr, valueDataPtr + valueDataLen);
524 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
525 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
526 int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->SetConfigurationByteArray(name, value);
527 if (ret != napi_ok) {
528 DRM_ERR_LOG("SetConfigurationByteArray failed!");
529 NapiDrmError::ThrowError(env, "SetConfigurationByteArray failed, service error.", DRM_SERVICE_FATAL_ERROR);
530 return result;
531 }
532 } else {
533 DRM_ERR_LOG("napi_unwrap call Failed!");
534 NapiDrmError::ThrowError(env, "Set configuration failed, unknown error.", DRM_UNKNOWN_ERROR);
535 return result;
536 }
537 return result;
538 }
539
GetConfigurationByteArray(napi_env env,napi_callback_info info)540 napi_value MediaKeySystemNapi::GetConfigurationByteArray(napi_env env, napi_callback_info info)
541 {
542 DRM_INFO_LOG("GetConfigurationByteArray enter");
543 napi_value result = nullptr;
544 size_t argc = ARGS_TWO;
545 napi_value argv[ARGS_TWO] = {0};
546 napi_value thisVar = nullptr;
547 napi_status status;
548 char nameStr[PATH_MAX];
549 size_t nameStrLength = 0;
550 std::vector<uint8_t> value;
551 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
552 napi_get_undefined(env, &result);
553
554 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
555 NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum");
556
557 status = napi_get_value_string_utf8(env, argv[PARAM0], nameStr, PATH_MAX, &nameStrLength);
558 if (status != napi_ok) {
559 DRM_ERR_LOG("Could not able to read name argument!");
560 NapiDrmError::ThrowError(env, "The param configName is missing or too long.", DRM_INVALID_PARAM);
561 return result;
562 }
563 std::string name = std::string(nameStr);
564 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
565 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
566 int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetConfigurationByteArray(name, value);
567 if (ret != napi_ok) {
568 DRM_ERR_LOG("GetConfigurationByteArray failed!");
569 NapiDrmError::ThrowError(env, "GetConfigurationByteArray failed, service error.", DRM_SERVICE_FATAL_ERROR);
570 return result;
571 }
572 } else {
573 DRM_ERR_LOG("napi_unwrap Failed!");
574 NapiDrmError::ThrowError(env, "GetConfigurationByteArray failed.", DRM_UNKNOWN_ERROR);
575 return result;
576 }
577 size_t valueLen = value.size();
578 NAPI_CALL(env, napi_create_array(env, &result));
579 for (size_t i = 0; i < valueLen; i++) {
580 napi_value item;
581 napi_create_int32(env, value[i], &item);
582 napi_set_element(env, result, i, item);
583 }
584 return result;
585 }
586
GetMaxContentProtectionLevel(napi_env env,napi_callback_info info)587 napi_value MediaKeySystemNapi::GetMaxContentProtectionLevel(napi_env env, napi_callback_info info)
588 {
589 DRM_INFO_LOG("GetMaxContentProtectionLevel enter.");
590 napi_value result = nullptr;
591 size_t argc = ARGS_ONE;
592 napi_value argv[ARGS_ONE] = {0};
593 napi_value thisVar = nullptr;
594 napi_status status;
595 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
596
597 napi_get_undefined(env, &result);
598 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
599 NAPI_ASSERT(env, argc <= ARGS_ONE, "requires one parameters maximum");
600 IMediaKeySessionService::ContentProtectionLevel level = IMediaKeySessionService::CONTENT_PROTECTION_LEVEL_UNKNOWN;
601 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
602 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
603 int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetMaxContentProtectionLevel(&level);
604 if (ret != napi_ok) {
605 DRM_ERR_LOG("GetCertificateStatus failed!");
606 NapiDrmError::ThrowError(env, "GetMaxContentProtectionLevel failed, service error.",
607 DRM_SERVICE_FATAL_ERROR);
608 return result;
609 }
610 } else {
611 DRM_ERR_LOG("napi_unwrap call Failed!");
612 NapiDrmError::ThrowError(env, "GetMaxContentProtectionLevel failed, unknown error.", DRM_UNKNOWN_ERROR);
613 return result;
614 }
615
616 NAPI_CALL(env, napi_create_int32(env, (int32_t)level, &result));
617 return result;
618 }
619
CheckMediaKeySystemStatus(MediaKeySystemNapi * napi,std::shared_ptr<MediaKeySystemAsyncContext> context)620 bool MediaKeySystemNapi::CheckMediaKeySystemStatus(MediaKeySystemNapi *napi,
621 std::shared_ptr<MediaKeySystemAsyncContext> context)
622 {
623 DRM_NAPI_CHECK_AND_RETURN_LOG(napi != nullptr, false, "napi object is nullptr.");
624 if (napi->mediaKeySystemImpl_ == nullptr) {
625 context->SignError(DRM_SERVICE_FATAL_ERROR);
626 return false;
627 }
628 return true;
629 }
630
CheckContextStatus(std::shared_ptr<MediaKeySystemAsyncContext> context)631 bool MediaKeySystemNapi::CheckContextStatus(std::shared_ptr<MediaKeySystemAsyncContext> context)
632 {
633 DRM_NAPI_CHECK_AND_RETURN_LOG(context != nullptr, false, "context object is nullptr.");
634 if (context->native == nullptr) {
635 context->SignError(DRM_SERVICE_FATAL_ERROR);
636 return false;
637 }
638 return true;
639 }
640
GenerateKeySystemRequest(napi_env env,napi_callback_info info)641 napi_value MediaKeySystemNapi::GenerateKeySystemRequest(napi_env env, napi_callback_info info)
642 {
643 DRM_INFO_LOG("GenerateKeySystemRequest enter");
644 DrmTrace trace("MediaKeySystemNapi::GenerateKeySystemRequest");
645 auto context = std::make_shared<MediaKeySystemAsyncContext>();
646 if (context == nullptr) {
647 DRM_ERR_LOG("GenerateKeySystemRequest failed.");
648 NapiDrmError::ThrowError(env, "make context failed, unknown error.", DRM_UNKNOWN_ERROR);
649 return NapiParamUtils::GetUndefinedValue(env);
650 }
651
652 context->GetCbInfo(env, info);
653
654 auto executor = [context]() {
655 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckContextStatus(context), "context object state is error.");
656 auto obj = reinterpret_cast<MediaKeySystemNapi *>(context->native);
657 ObjectRefMap objectGuard(obj);
658 auto *napiMediaKeySystem = objectGuard.GetPtr();
659 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckMediaKeySystemStatus(napiMediaKeySystem, context),
660 "context object state is error.");
661 context->intValue = napiMediaKeySystem->mediaKeySystemImpl_->GenerateKeySystemRequest(
662 context->provisionRequest.data, context->provisionRequest.defaultURL);
663 if (context->intValue != 0) {
664 context->SignError(DRM_SERVICE_FATAL_ERROR);
665 }
666 };
667
668 auto complete = [env, context](napi_value &output) {
669 NapiParamUtils::SetProvisionRequest(env, context->provisionRequest, output);
670 };
671 return NapiAsyncWork::Enqueue(env, context, "GenerateKeySystemRequest", executor, complete);
672 }
673
ProcessKeySystemResponse(napi_env env,napi_callback_info info)674 napi_value MediaKeySystemNapi::ProcessKeySystemResponse(napi_env env, napi_callback_info info)
675 {
676 DRM_INFO_LOG("ProcessKeySystemResponse enter.");
677 int64_t beginTime = std::chrono::duration_cast<std::chrono::milliseconds>(
678 std::chrono::system_clock::now().time_since_epoch()).count();
679 DrmTrace trace("MediaKeySystemNapi::ProcessKeySystemResponse");
680 auto context = std::make_shared<MediaKeySystemAsyncContext>();
681 if (context == nullptr) {
682 DRM_ERR_LOG("ProcessKeySystemResponse failed.");
683 NapiDrmError::ThrowError(env, "make context failed, unknown error.", DRM_UNKNOWN_ERROR);
684 return NapiParamUtils::GetUndefinedValue(env);
685 }
686
687 auto inputParser = [env, context](size_t argc, napi_value *argv) {
688 NAPI_CHECK_ARGS_RETURN_VOID(context, argc == ARGS_ONE, "invalid arguments", DRM_INVALID_PARAM);
689 context->status = NapiParamUtils::GetValueUint8Array(env, context->response, argv[PARAM0]);
690 NAPI_CHECK_STATUS_RETURN_VOID(context, "ProcessKeySystemResponse failed.", DRM_INVALID_PARAM);
691 };
692
693 context->GetCbInfo(env, info, inputParser);
694
695 auto executor = [context]() {
696 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckContextStatus(context), "context object state is error.");
697 auto obj = reinterpret_cast<MediaKeySystemNapi *>(context->native);
698 ObjectRefMap objectGuard(obj);
699 auto *napiMediaKeySystem = objectGuard.GetPtr();
700 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckMediaKeySystemStatus(napiMediaKeySystem, context),
701 "context object state is error.");
702 context->intValue = napiMediaKeySystem->mediaKeySystemImpl_->ProcessKeySystemResponse(context->response);
703 if (context->intValue != DRM_OK) {
704 context->SignError(DRM_SERVICE_FATAL_ERROR);
705 }
706 };
707
708 auto complete = [env](napi_value &output) { output = NapiParamUtils::GetUndefinedValue(env); };
709 ConfigParser::WriteEndEvent(0, 0, std::string("processKeySystemResponse"), beginTime);
710 return NapiAsyncWork::Enqueue(env, context, "ProcessKeySystemResponse", executor, complete);
711 }
712
vectorToJsArray(napi_env env,std::vector<IMediaKeySystemService::MetircKeyValue> & metrics)713 static napi_value vectorToJsArray(napi_env env, std::vector<IMediaKeySystemService::MetircKeyValue> &metrics)
714 {
715 DRM_INFO_LOG("vectorToJsArray enter.");
716 napi_value jsArray;
717 napi_create_array_with_length(env, metrics.size(), &jsArray);
718 for (size_t i = 0; i < metrics.size(); i++) {
719 napi_value jsObject;
720 napi_value jsName;
721 napi_value jsValue;
722 napi_create_object(env, &jsObject);
723 napi_create_string_utf8(env, metrics[i].name.c_str(), NAPI_AUTO_LENGTH, &jsName);
724 napi_set_named_property(env, jsObject, "name", jsName);
725 napi_create_string_utf8(env, metrics[i].value.c_str(), NAPI_AUTO_LENGTH, &jsValue);
726 napi_set_named_property(env, jsObject, "value", jsValue);
727
728 napi_set_element(env, jsArray, i, jsObject);
729 }
730 return jsArray;
731 }
732
GetStatistics(napi_env env,napi_callback_info info)733 napi_value MediaKeySystemNapi::GetStatistics(napi_env env, napi_callback_info info)
734 {
735 DRM_INFO_LOG("GetStatistics enter.");
736 napi_value result = nullptr;
737 size_t argc = ARGS_ZERO;
738 napi_value argv[ARGS_ZERO];
739 napi_value thisVar = nullptr;
740 napi_status status;
741 std::vector<IMediaKeySystemService::MetircKeyValue> metrics;
742 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
743 napi_get_undefined(env, &result);
744
745 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
746 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
747 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
748 int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetStatistics(metrics);
749 if (ret != napi_ok) {
750 DRM_ERR_LOG("GetStatistics failed!");
751 NapiDrmError::ThrowError(env, "Get statistics failed, service error.", DRM_SERVICE_FATAL_ERROR);
752 return result;
753 }
754 } else {
755 DRM_ERR_LOG("napi_unwrap Failed!");
756 NapiDrmError::ThrowError(env, "GetStatistics failed, unknown error.", DRM_UNKNOWN_ERROR);
757 return result;
758 }
759 result = vectorToJsArray(env, metrics);
760 return result;
761 }
762
GetCertificateStatus(napi_env env,napi_callback_info info)763 napi_value MediaKeySystemNapi::GetCertificateStatus(napi_env env, napi_callback_info info)
764 {
765 DrmTrace trace("MediaKeySystemNapi::GetCertificateStatus");
766 DRM_INFO_LOG("GetCertificateStatus enter.");
767 napi_value result = nullptr;
768 size_t argc = ARGS_ZERO;
769 napi_value argv[ARGS_ZERO];
770 napi_value thisVar = nullptr;
771 napi_status status;
772 IMediaKeySystemService::CertificateStatus certStatus;
773 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
774
775 napi_get_undefined(env, &result);
776 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
777 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
778 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
779 int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetCertificateStatus(&certStatus);
780 if (ret != napi_ok) {
781 DRM_ERR_LOG("GetCertificateStatus failed!");
782 NapiDrmError::ThrowError(env, "GetCertificateStatus failed, service error.", DRM_SERVICE_FATAL_ERROR);
783 return result;
784 }
785 } else {
786 DRM_ERR_LOG("napi_unwrap Failed!");
787 NapiDrmError::ThrowError(env, "GetCertificateStatus failed, unknown error.", DRM_UNKNOWN_ERROR);
788 return result;
789 }
790 NAPI_CALL(env, napi_create_int32(env, (int32_t)certStatus, &result));
791 return result;
792 }
793
vectorToJs2DArray(napi_env env,std::vector<std::vector<uint8_t>> vec,napi_value result)794 static napi_value vectorToJs2DArray(napi_env env, std::vector<std::vector<uint8_t>> vec, napi_value result)
795 {
796 DRM_INFO_LOG("vectorToJs2DArray enter.");
797 napi_value outArray;
798 napi_value inArray;
799 napi_status status = napi_create_array(env, &outArray);
800 if (status != napi_ok) {
801 DRM_ERR_LOG("napi_create_array failed!");
802 NapiDrmError::ThrowError(env, "napi_create_array failed.", DRM_UNKNOWN_ERROR);
803 return result;
804 }
805
806 for (size_t i = 0; i < vec.size(); i++) {
807 status = napi_create_array(env, &inArray);
808 if (status != napi_ok) {
809 DRM_ERR_LOG("napi_create_array failed!");
810 NapiDrmError::ThrowError(env, "napi_create_array failed.", DRM_UNKNOWN_ERROR);
811 return result;
812 }
813
814 for (size_t j = 0; j < vec[i].size(); j++) {
815 napi_value elem;
816 status = napi_create_uint32(env, vec[i][j], &elem);
817 if (status != napi_ok) {
818 DRM_ERR_LOG("napi_create_uint32 failed!");
819 NapiDrmError::ThrowError(env, "napi_create_uint32 failed.", DRM_UNKNOWN_ERROR);
820 return result;
821 }
822 status = napi_set_element(env, inArray, j, elem);
823 if (status != napi_ok) {
824 DRM_ERR_LOG("napi_set_element failed!");
825 NapiDrmError::ThrowError(env, "napi_set_element failed.", DRM_UNKNOWN_ERROR);
826 return result;
827 }
828 }
829 status = napi_set_element(env, outArray, i, inArray);
830 if (status != napi_ok) {
831 DRM_ERR_LOG("napi_set_element failed!");
832 NapiDrmError::ThrowError(env, "napi_set_element failed.", DRM_UNKNOWN_ERROR);
833 return result;
834 }
835 }
836 return outArray;
837 }
838
GetOfflineMediaKeyIds(napi_env env,napi_callback_info info)839 napi_value MediaKeySystemNapi::GetOfflineMediaKeyIds(napi_env env, napi_callback_info info)
840 {
841 DRM_INFO_LOG("GetOfflineMediaKeyIds enter.");
842 napi_value result = nullptr;
843 size_t argc = ARGS_ZERO;
844 napi_value argv[ARGS_ZERO];
845 napi_value thisVar = nullptr;
846 napi_status status;
847 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
848
849 napi_get_undefined(env, &result);
850 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
851 NAPI_ASSERT(env, argc >= ARGS_ZERO, "requires 0 parameters maximum");
852 std::vector<std::vector<uint8_t>> licenseIds;
853 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
854 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
855 int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetOfflineMediaKeyIds(licenseIds);
856 if (ret != napi_ok) {
857 DRM_ERR_LOG("napi GetOfflineMediaKeyIds failed!");
858 NapiDrmError::ThrowError(env, "GetOfflineMediaKeyIds failed, service error.", DRM_SERVICE_FATAL_ERROR);
859 return result;
860 }
861 } else {
862 DRM_ERR_LOG("napi_unwrap call Failed!");
863 NapiDrmError::ThrowError(env, "GetOfflineMediaKeyIds failed, unknown error.", DRM_UNKNOWN_ERROR);
864 return result;
865 }
866
867 result = vectorToJs2DArray(env, licenseIds, result);
868 return result;
869 }
870
GetOfflineMediaKeyStatus(napi_env env,napi_callback_info info)871 napi_value MediaKeySystemNapi::GetOfflineMediaKeyStatus(napi_env env, napi_callback_info info)
872 {
873 DRM_INFO_LOG("GetOfflineMediaKeyStatus enter");
874 napi_value result = nullptr;
875 size_t argc = ARGS_ONE;
876 napi_value argv[ARGS_ONE] = {0};
877 napi_value thisVar = nullptr;
878 napi_status status;
879 void *licenseId = nullptr;
880 size_t licenseIdLen;
881 size_t offset;
882 napi_value arraybuffer = nullptr;
883 napi_typedarray_type type;
884 bool isTypeArray;
885 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
886
887 napi_get_undefined(env, &result);
888 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
889 NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum");
890 napi_is_typedarray(env, argv[PARAM0], &isTypeArray);
891 if (!isTypeArray) {
892 DRM_ERR_LOG("First parame is not array!");
893 NapiDrmError::ThrowError(env, "The param mediaKeyId type is not array.", DRM_INVALID_PARAM);
894 return result;
895 }
896 napi_get_typedarray_info(env, argv[PARAM0], &type, &licenseIdLen, &licenseId, &arraybuffer, &offset);
897 if (licenseId == nullptr) {
898 DRM_ERR_LOG("napi_get_typedarray_info failed!");
899 NapiDrmError::ThrowError(env, "The param mediaKeyId is invalid.", DRM_INVALID_PARAM);
900 return result;
901 }
902 uint8_t *licenseIdPtr = reinterpret_cast<uint8_t *>(licenseId);
903 std::vector<uint8_t> licenseIdVec(licenseIdPtr, licenseIdPtr + licenseIdLen);
904 IMediaKeySessionService::OfflineMediaKeyStatus offlineMediaKeyStatus =
905 IMediaKeySessionService::OFFLINELICENSESTATUS_UNKNOWN;
906 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
907 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
908 int32_t ret =
909 mediaKeySystemNapi->mediaKeySystemImpl_->GetOfflineMediaKeyStatus(licenseIdVec, offlineMediaKeyStatus);
910 if (ret != napi_ok) {
911 DRM_ERR_LOG("GetOfflineMediaKeyStatus failed!");
912 NapiDrmError::ThrowError(env, "GetOfflineMediaKeyStatus failed, service error.", DRM_SERVICE_FATAL_ERROR);
913 return result;
914 }
915 } else {
916 DRM_ERR_LOG("napi_unwrap call Failed!");
917 NapiDrmError::ThrowError(env, "GetOfflineMediaKeyStatus failed, unknown error.", DRM_UNKNOWN_ERROR);
918 return result;
919 }
920
921 NAPI_CALL(env, napi_create_int32(env, (int32_t)offlineMediaKeyStatus, &result));
922 return result;
923 }
924
ClearOfflineMediaKeys(napi_env env,napi_callback_info info)925 napi_value MediaKeySystemNapi::ClearOfflineMediaKeys(napi_env env, napi_callback_info info)
926 {
927 DRM_INFO_LOG("ClearOfflineMediaKeys enter.");
928 napi_value result = nullptr;
929 size_t argc = ARGS_ONE;
930 napi_value argv[ARGS_ONE] = {0};
931 napi_value thisVar = nullptr;
932 napi_status status;
933 bool isTypeArray;
934 void *licenseId = nullptr;
935 size_t licenseIdLen;
936 size_t offset;
937 napi_value arraybuffer = nullptr;
938 napi_typedarray_type type;
939 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
940
941 napi_get_undefined(env, &result);
942 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
943 NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 2 parameters maximum");
944 napi_is_typedarray(env, argv[PARAM0], &isTypeArray);
945 if (!isTypeArray) {
946 DRM_ERR_LOG("argv[PARAM0] is not array!");
947 NapiDrmError::ThrowError(env, "The param mediaKeyId is not array.", DRM_INVALID_PARAM);
948 return result;
949 }
950 napi_get_typedarray_info(env, argv[PARAM0], &type, &licenseIdLen, &licenseId, &arraybuffer, &offset);
951 if (licenseId == nullptr) {
952 DRM_ERR_LOG("napi_get_typedarray_info failed!");
953 NapiDrmError::ThrowError(env, "ClearOfflineMediaKeys failed, unknown error.", DRM_UNKNOWN_ERROR);
954 return result;
955 }
956 uint8_t *licenseIdPtr = reinterpret_cast<uint8_t *>(licenseId);
957 std::vector<uint8_t> licenseIdVec(licenseIdPtr, licenseIdPtr + licenseIdLen);
958 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
959 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
960 int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->ClearOfflineMediaKeys(licenseIdVec);
961 if (ret != napi_ok) {
962 DRM_ERR_LOG("ClearOfflineMediaKeys failed!");
963 NapiDrmError::ThrowError(env, "ClearOfflineMediaKeys failed, service error.", DRM_SERVICE_FATAL_ERROR);
964 return result;
965 }
966 } else {
967 DRM_ERR_LOG("ClearOfflineMediaKeys call Failed!");
968 NapiDrmError::ThrowError(env, "ClearOfflineMediaKeys failed, unknown error.", DRM_UNKNOWN_ERROR);
969 return result;
970 }
971
972 return result;
973 }
974
Destroy(napi_env env,napi_callback_info info)975 napi_value MediaKeySystemNapi::Destroy(napi_env env, napi_callback_info info)
976 {
977 DRM_INFO_LOG("Release enter.");
978 int32_t currentPid = IPCSkeleton::GetCallingPid();
979 DRM_DEBUG_LOG("GetCallingPID: %{public}d", currentPid);
980
981 napi_status status;
982 napi_value result = nullptr;
983 size_t argc = ARGS_ZERO;
984 napi_value argv[ARGS_ZERO];
985 napi_value thisVar = nullptr;
986 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
987
988 napi_get_undefined(env, &result);
989 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
990 napi_get_undefined(env, &result);
991 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
992 if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) {
993 int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->Release();
994 if (ret != napi_ok) {
995 DRM_ERR_LOG("GetCertificateStatus failed!");
996 NapiDrmError::ThrowError(env, "Destroy failed, service error.", DRM_SERVICE_FATAL_ERROR);
997 return result;
998 }
999 } else {
1000 DRM_ERR_LOG("napi_unwrap Failed!");
1001 NapiDrmError::ThrowError(env, "Destroy failed.", DRM_UNKNOWN_ERROR);
1002 return result;
1003 }
1004 return result;
1005 }
1006
SaveEventCallbackReferrence(const std::string eventType,std::shared_ptr<AutoRef> callbackPair)1007 void MediaKeySystemNapi::SaveEventCallbackReferrence(const std::string eventType, std::shared_ptr<AutoRef> callbackPair)
1008 {
1009 DRM_INFO_LOG("SaveEventCallbackReferrence");
1010 std::lock_guard<std::mutex> lock(mutex_);
1011 if (mediaKeySystemCallbackNapi_ != nullptr) {
1012 mediaKeySystemCallbackNapi_->SetCallbackReference(eventType, callbackPair);
1013 } else {
1014 DRM_ERR_LOG("SaveEventCallbackReferrence failed.");
1015 }
1016 }
1017
ClearEventCallbackReferrence(const std::string eventType)1018 void MediaKeySystemNapi::ClearEventCallbackReferrence(const std::string eventType)
1019 {
1020 DRM_INFO_LOG("ClearEventCallbackReference");
1021 if (mediaKeySystemCallbackNapi_ != nullptr) {
1022 mediaKeySystemCallbackNapi_->ClearCallbackReference(eventType);
1023 } else {
1024 DRM_ERR_LOG("ClearEventCallbackReference failed.");
1025 }
1026 }
1027
SetEventCallback(napi_env env,napi_callback_info info)1028 napi_value MediaKeySystemNapi::SetEventCallback(napi_env env, napi_callback_info info)
1029 {
1030 DRM_INFO_LOG("SetEventCallback");
1031 napi_value result = nullptr;
1032 napi_get_undefined(env, &result);
1033 size_t length = 0;
1034 size_t argc = ARGS_TWO;
1035 napi_value thisVar = nullptr;
1036 napi_value argv[ARGS_TWO] = { nullptr };
1037 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1038 NAPI_ASSERT(env, argc == ARGS_TWO, "only requires 2 parameters");
1039 if (thisVar == nullptr || argv[PARAM0] == nullptr || argv[PARAM1] == nullptr) {
1040 NapiDrmError::ThrowError(env, "Mandatory parameters are left unspecified.", DRM_INVALID_PARAM);
1041 DRM_ERR_LOG("Failed to retrieve arguments in SetEventCallback!");
1042 return result;
1043 }
1044 napi_valuetype valueType = napi_undefined;
1045 if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string ||
1046 napi_typeof(env, argv[PARAM1], &valueType) != napi_ok || valueType != napi_function) {
1047 NapiDrmError::ThrowError(env, "Mandatory parameter type is invalid.", DRM_INVALID_PARAM);
1048 return result;
1049 }
1050
1051 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
1052 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
1053 if (status == napi_ok && mediaKeySystemNapi != nullptr) {
1054 char buffer[PATH_MAX];
1055 napi_get_value_string_utf8(env, argv[PARAM0], buffer, PATH_MAX, &length);
1056 std::string eventType = std::string(buffer);
1057 napi_ref callbackRef;
1058 napi_create_reference(env, argv[PARAM1], 1, &callbackRef);
1059 DRM_INFO_LOG("SetEventCallback event is %{public}s", eventType.c_str());
1060
1061 std::shared_ptr<AutoRef> callbackPair = std::make_shared<AutoRef>(env, callbackRef);
1062 mediaKeySystemNapi->SaveEventCallbackReferrence(eventType, callbackPair);
1063 DRM_INFO_LOG("SetEventCallback out");
1064 } else {
1065 NapiDrmError::ThrowError(env, "SetEventCallback failed, unknown error.", DRM_UNKNOWN_ERROR);
1066 DRM_ERR_LOG("SetEventCallback failed!");
1067 }
1068 return result;
1069 }
1070
UnsetEventCallback(napi_env env,napi_callback_info info)1071 napi_value MediaKeySystemNapi::UnsetEventCallback(napi_env env, napi_callback_info info)
1072 {
1073 DRM_INFO_LOG("UnsetEventCallback");
1074 napi_value result = nullptr;
1075 napi_get_undefined(env, &result);
1076 napi_value thisVar = nullptr;
1077 napi_value argv[ARGS_ONE] = { nullptr };
1078 size_t argc = 1;
1079 DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1080 NAPI_ASSERT(env, argc == ARGS_ONE, "only requires 1 parameters");
1081 if (thisVar == nullptr || argv[PARAM0] == nullptr) {
1082 DRM_ERR_LOG("Failed to retrieve arguments in UnsetEventCallback!");
1083 NapiDrmError::ThrowError(env, "The param callback type is missing.", DRM_INVALID_PARAM);
1084 return result;
1085 }
1086 napi_valuetype valueType = napi_undefined;
1087 if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string) {
1088 DRM_ERR_LOG("Failed to retrieve reasonable arguments in UnsetEventCallback!");
1089 NapiDrmError::ThrowError(env, "The param callback type is not string.", DRM_INVALID_PARAM);
1090 return result;
1091 }
1092
1093 MediaKeySystemNapi *mediaKeySystemNapi = nullptr;
1094 char buffer[PATH_MAX];
1095 size_t length = 0;
1096 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&mediaKeySystemNapi));
1097 if (status == napi_ok && mediaKeySystemNapi != nullptr) {
1098 napi_get_value_string_utf8(env, argv[PARAM0], buffer, PATH_MAX, &length);
1099 std::string eventType = std::string(buffer);
1100 mediaKeySystemNapi->ClearEventCallbackReferrence(eventType);
1101 DRM_INFO_LOG("UnsetEventCallback out");
1102 } else {
1103 NapiDrmError::ThrowError(env, "UnsetEventCallback failed, unknown error.", DRM_UNKNOWN_ERROR);
1104 DRM_ERR_LOG("UnsetEventCallback failed!");
1105 }
1106 return result;
1107 }
1108 } // namespace DrmStandard
1109 } // namespace OHOS