diff --git a/README_zh.md b/README_zh.md index fa0fbeb3..3f328b76 100644 --- a/README_zh.md +++ b/README_zh.md @@ -55,13 +55,13 @@ DRM框架组件提供以下功能: ~~~js import drm from '@ohos.multimedia.drm'; ~~~ -2.判断DRM框架是否支持指定的DRM方案, 示例以'com.drm.clearplay'为例。 +2.判断DRM框架是否支持指定的DRM方案, 示例以'com.clearplay.drm'为例。 ~~~js -var isSupported = drm.isMediaKeySystemSupported('com.drm.clearplay'); +var isSupported = drm.isMediaKeySystemSupported('com.clearplay.drm'); ~~~ 3.创建MediaKeySystem实例, ~~~js -var keySystem = drm.createMediaKeySystem('com.drm.clearplay'); +var keySystem = drm.createMediaKeySystem('com.clearplay.drm'); ~~~ 4.如无本地DRM证书,需完成证书下载。 ~~~js diff --git a/bundle.json b/bundle.json index 66f36a45..01f76298 100644 --- a/bundle.json +++ b/bundle.json @@ -20,6 +20,8 @@ "hisysevent_config": [ ], "deps": { "components": [ + "ability_base", + "ability_runtime", "safwk", "napi", "samgr", @@ -33,8 +35,7 @@ "hdf_core", "eventhandler", "bundle_framework", - "drivers_interface_drm", - "ability_base" + "drivers_interface_drm" ] }, "build": { diff --git a/frameworks/c/drm_capi/native_mediakeysession.cpp b/frameworks/c/drm_capi/native_mediakeysession.cpp index 6abe340f..fe93add4 100644 --- a/frameworks/c/drm_capi/native_mediakeysession.cpp +++ b/frameworks/c/drm_capi/native_mediakeysession.cpp @@ -19,7 +19,6 @@ #include #include #include "drm_log.h" -#include "drm_error_code.h" #include "native_drm_base.h" #include "native_drm_object.h" #include "key_session_impl.h" @@ -68,7 +67,7 @@ Drm_ErrCode OH_MediaKeySession_GenerateMediaKeyRequest(MediaKeySession *mediaKey } MediaKeySessionObject *sessionObject = reinterpret_cast(mediaKeySession); int ret = sessionObject->sessionImpl_->GenerateMediaKeyRequest(licenseRequestInfo, licenseRequest); - DRM_CHECK_AND_RETURN_RET_LOG((ret == DRM_OK), DRM_ERR_INVALID_VAL, + DRM_CHECK_AND_RETURN_RET_LOG((ret == DRM_ERR_OK), DRM_ERR_INVALID_VAL, "OH_MediaKeySession_GenerateMediaKeyRequest call Failed!"); Drm_ErrCode result = DealMediaKeyRequest(licenseRequest, mediaKeyRequest); DRM_INFO_LOG("OH_MediaKeySession_GenerateMediaKeyRequest exit"); @@ -79,7 +78,7 @@ Drm_ErrCode OH_MediaKeySession_ProcessMediaKeyResponse(MediaKeySession *mediaKey int32_t responseLen, uint8_t *offlineMediaKeyId, int32_t *offlineMediaKeyIdLen) { DRM_CHECK_AND_RETURN_RET_LOG( - ((mediaKeySession != nullptr) && (response != nullptr) && (responseLen != 0) && + ((mediaKeySession != nullptr) && (response != nullptr) && (responseLen > 0) && (offlineMediaKeyId != nullptr) && (offlineMediaKeyIdLen != nullptr)), DRM_ERR_INVALID_VAL, "params is nullptr!"); MediaKeySessionObject *sessionObject = reinterpret_cast(mediaKeySession); @@ -160,7 +159,7 @@ Drm_ErrCode OH_MediaKeySession_GenerateOfflineReleaseRequest(MediaKeySession *me { DRM_INFO_LOG("OH_MediaKeySession_GenerateOfflineReleaseRequest enter"); DRM_CHECK_AND_RETURN_RET_LOG(((mediaKeySessoin != nullptr) && (offlineMediaKeyId != nullptr) && - (offlineMediaKeyIdLen != 0) && (releaseRequest != nullptr) && (releaseRequestLen != nullptr)), + (offlineMediaKeyIdLen > 0) && (releaseRequest != nullptr) && (releaseRequestLen != nullptr)), DRM_ERR_INVALID_VAL, "OH_MediaKeySession_GenerateOfflineReleaseRequest keySession is nullptr!"); std::vector ReleaseRequest; std::vector licenseIdVec(offlineMediaKeyId, offlineMediaKeyId + offlineMediaKeyIdLen); @@ -189,7 +188,7 @@ Drm_ErrCode OH_MediaKeySession_ProcessOfflineReleaseResponse(MediaKeySession *me { DRM_INFO_LOG("OH_MediaKeySession_ProcessOfflineReleaseResponse enter."); DRM_CHECK_AND_RETURN_RET_LOG(((mediaKeySessoin != nullptr) && (offlineMediaKeyId != nullptr) && - (offlineMediaKeyIdLen != 0) && (releaseReponse != nullptr) && (releaseReponseLen != 0)), + (offlineMediaKeyIdLen > 0) && (releaseReponse != nullptr) && (releaseReponseLen > 0)), DRM_ERR_INVALID_VAL, "OH_MediaKeySession_ClearMediaKeys keySession is nullptr!"); std::vector licenseIdVec(offlineMediaKeyId, offlineMediaKeyId + offlineMediaKeyIdLen); std::vector responseVec(releaseReponse, releaseReponse + releaseReponseLen); diff --git a/frameworks/c/drm_capi/native_mediakeysystem.cpp b/frameworks/c/drm_capi/native_mediakeysystem.cpp index d65b5246..9fc29ccc 100644 --- a/frameworks/c/drm_capi/native_mediakeysystem.cpp +++ b/frameworks/c/drm_capi/native_mediakeysystem.cpp @@ -19,7 +19,6 @@ #include #include #include "drm_log.h" -#include "drm_error_code.h" #include "native_drm_common.h" #include "native_drm_base.h" #include "native_drm_object.h" @@ -73,7 +72,7 @@ bool OH_MediaKeySystem_IsSupported3(const char *uuid, const char *mimeType, IMediaKeySessionService::ContentProtectionLevel securityLevel = (IMediaKeySessionService::ContentProtectionLevel)ContentProtectionLevel; - if ((securityLevel < IMediaKeySessionService::CONTENT_PROTECTION_LEVEL_UNKNOWN) || + if ((securityLevel <= IMediaKeySessionService::CONTENT_PROTECTION_LEVEL_UNKNOWN) || (securityLevel >= IMediaKeySessionService::CONTENT_PROTECTION_LEVEL_MAX)) { DRM_ERR_LOG("ContentProtectionLevel is invalid"); return false; @@ -138,7 +137,7 @@ Drm_ErrCode OH_MediaKeySystem_GetConfigurationString(MediaKeySystem *mediaKeySys { DRM_INFO_LOG("OH_GetConfigurationString enter"); DRM_CHECK_AND_RETURN_RET_LOG( - ((mediaKeySystem != nullptr) && (configName != nullptr) && (value != nullptr) && (valueLen != 0)), + ((mediaKeySystem != nullptr) && (configName != nullptr) && (value != nullptr) && (valueLen > 0)), DRM_ERR_INVALID_VAL, "OH_GetConfigurationString params is error!"); std::string valuePtr; @@ -287,7 +286,7 @@ Drm_ErrCode OH_MediaKeySystem_GenerateKeySystemRequest(MediaKeySystem *mediaKeyS { DRM_INFO_LOG("OH_MediaKeySystem_GenerateKeySystemRequest enter"); DRM_CHECK_AND_RETURN_RET_LOG(((mediaKeySystem != nullptr) && (request != nullptr) && (requestLen != nullptr) && - (defaultUrl != nullptr) && (defaultUrlLen != 0)), + (defaultUrl != nullptr) && (defaultUrlLen > 0)), DRM_ERR_INVALID_VAL, "OH_MediaKeySystem_GenerateKeySystemRequest mediaKeySystem is nullptr!"); std::vector requestData; std::string defaultUrlData; @@ -316,7 +315,7 @@ Drm_ErrCode OH_MediaKeySystem_ProcessKeySystemResponse(MediaKeySystem *mediaKeyS uint8_t *response, int32_t responseLen) { DRM_INFO_LOG("OH_ProcessKeySystemResponse enter."); - DRM_CHECK_AND_RETURN_RET_LOG(((mediaKeySystem != nullptr) && (response != nullptr) && (responseLen != 0)), + DRM_CHECK_AND_RETURN_RET_LOG(((mediaKeySystem != nullptr) && (response != nullptr) && (responseLen > 0)), DRM_ERR_INVALID_VAL, "OH_ProcessKeySystemResponse mediaKeySystem is nullptr!"); int32_t result = DRM_ERR_OK; std::vector keySystemResponse(response, response + responseLen); @@ -366,7 +365,7 @@ Drm_ErrCode OH_MediaKeySystem_CreateMediaKeySession(MediaKeySystem *mediaKeySyst MediaKeySession **mediaKeySession) { DRM_CHECK_AND_RETURN_RET_LOG(((mediaKeySystem != nullptr) && (level != nullptr) && (mediaKeySession != nullptr) && - (*level > CONTENT_PROTECTION_LEVEL_UNKNOWN) && (*level <= CONTENT_PROTECTION_LEVEL_MAX)), + (*level > CONTENT_PROTECTION_LEVEL_UNKNOWN) && (*level < CONTENT_PROTECTION_LEVEL_MAX)), DRM_ERR_INVALID_VAL, "mediaKeySystem is nullptr!"); struct MediaKeySystemObject *systemObject = reinterpret_cast(mediaKeySystem); @@ -442,7 +441,7 @@ Drm_ErrCode OH_MediaKeySystem_GetOfflineMediaKeyStatus(MediaKeySystem *mediaKeyS { DRM_INFO_LOG("OH_MediaKeySystem_GetOfflineMediaKeyStatus enter"); DRM_CHECK_AND_RETURN_RET_LOG(((mediaKeySystem != nullptr) && (offlineMediaKeyId != nullptr) && - (offlineMediaKeyIdLen != 0) && (status != nullptr)), + (offlineMediaKeyIdLen > 0) && (status != nullptr)), DRM_ERR_INVALID_VAL, "OH_MediaKeySystem_GetOfflineMediaKeyStatus mediaKeySystem is nullptr!"); int32_t result = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN; @@ -472,7 +471,7 @@ Drm_ErrCode OH_MediaKeySystem_ClearOfflineMediaKeys(MediaKeySystem *mediaKeySyst { DRM_INFO_LOG("OH_RemoveOfflineLMediaKey enter."); DRM_CHECK_AND_RETURN_RET_LOG(((mediaKeySystem != nullptr) && (offlineMediaKeyId != nullptr) && - (offlineMediaKeyIdLen != 0)), + (offlineMediaKeyIdLen > 0)), DRM_ERR_INVALID_VAL, "OH_GetOfflineMediaKeyStatus mediaKeySystem is nullptr!"); int32_t result = DRM_ERR_OK; std::vector licenseIdVec(offlineMediaKeyId, offlineMediaKeyId + offlineMediaKeyIdLen); diff --git a/frameworks/js/drm_napi/drm_enum_napi.cpp b/frameworks/js/drm_napi/drm_enum_napi.cpp index def24277..34e1a8ab 100644 --- a/frameworks/js/drm_napi/drm_enum_napi.cpp +++ b/frameworks/js/drm_napi/drm_enum_napi.cpp @@ -15,7 +15,7 @@ #include #include -#include "drm_napi_utils.h" +#include "napi_param_utils.h" #include "drm_enum_napi.h" namespace OHOS { diff --git a/frameworks/js/drm_napi/drm_error_code.cpp b/frameworks/js/drm_napi/drm_error_code.cpp new file mode 100644 index 00000000..492658cf --- /dev/null +++ b/frameworks/js/drm_napi/drm_error_code.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "drm_error_code.h" + +namespace OHOS { +namespace DrmStandard { +napi_status NapiDrmError::ThrowError(napi_env env, const char *napiMessage, int32_t napiCode) +{ + napi_value message = nullptr; + napi_value code = nullptr; + napi_value result = nullptr; + napi_create_string_utf8(env, napiMessage, NAPI_AUTO_LENGTH, &message); + napi_create_error(env, nullptr, message, &result); + napi_create_int32(env, napiCode, &code); + napi_set_named_property(env, result, "code", code); + napi_throw(env, result); + return napi_ok; +} + +void NapiDrmError::ThrowError(napi_env env, int32_t code) +{ + std::string messageValue = GetMessageByCode(code); + napi_throw_error(env, (std::to_string(code)).c_str(), messageValue.c_str()); +} + +std::string NapiDrmError::GetMessageByCode(int32_t &code) +{ + std::string errMessage; + switch (code) { + case DRM_INVALID_PARAM: + errMessage = DRM_INVALID_PARAM_INFO; + break; + case DRM_SERVICE_FATAL_ERROR: + errMessage = DRM_SERVICE_FATAL_ERRO_INFO; + break; + case DRM_UNKNOWN_ERROR: + errMessage = DRM_UNKNOWN_ERROR_INFO; + break; + case DRM_MAX_SYSTEM_NUM_REACHED: + errMessage = DRM_MAX_SYSTEM_NUM_REACHED_INFO; + break; + case DRM_MAX_SESSION_NUM_REACHED: + errMessage = DRM_MAX_SESSION_NUM_REACHED_INFO; + break; + default: + errMessage = DRM_UNKNOWN_ERROR_INFO; + code = DRM_UNKNOWN_ERROR; + break; + } + return errMessage; +} +} // namespace DrmStandard +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/drm_napi/drm_napi.cpp b/frameworks/js/drm_napi/drm_napi.cpp index c41b98af..aca577b8 100644 --- a/frameworks/js/drm_napi/drm_napi.cpp +++ b/frameworks/js/drm_napi/drm_napi.cpp @@ -14,7 +14,7 @@ */ #include "ipc_skeleton.h" -#include "drm_napi_utils.h" +#include "napi_param_utils.h" #include "drm_napi.h" namespace OHOS { diff --git a/frameworks/js/drm_napi/key_session_callback_napi.cpp b/frameworks/js/drm_napi/key_session_callback_napi.cpp index b421566e..ccd6ecc4 100644 --- a/frameworks/js/drm_napi/key_session_callback_napi.cpp +++ b/frameworks/js/drm_napi/key_session_callback_napi.cpp @@ -14,16 +14,19 @@ */ #include "drm_log.h" #include "drm_error_code.h" -#include "drm_napi_utils.h" #include "key_session_callback_napi.h" namespace OHOS { namespace DrmStandard { -MediaKeySessionCallbackNapi::MediaKeySessionCallbackNapi() {} +MediaKeySessionCallbackNapi::MediaKeySessionCallbackNapi(napi_env env) +{ + env_ = env; +} MediaKeySessionCallbackNapi::~MediaKeySessionCallbackNapi() {} -void MediaKeySessionCallbackNapi::SetCallbackReference(const std::string eventType, sptr callbackPair) +void MediaKeySessionCallbackNapi::SetCallbackReference(const std::string eventType, + std::shared_ptr callbackPair) { DRM_INFO_LOG("MediaKeySessionCallbackNapi SetCallbackReference"); std::lock_guard lock(mutex_); @@ -37,118 +40,111 @@ void MediaKeySessionCallbackNapi::ClearCallbackReference(const std::string event callbackMap_.erase(eventType); } -void MediaKeySessionCallbackNapi::SendEvent(const std::string event, int32_t extra, const std::vector data) +void MediaKeySessionCallbackNapi::WorkCallbackInterruptDone(uv_work_t *work, int status) { - DRM_INFO_LOG("MediaKeySessionCallbackNapi SendEvent %{public}s", event.c_str()); - DRM_NAPI_CHECK_AND_RETURN_LOG(!event.empty(), "Service event code error"); + // Js Thread + std::shared_ptr context(static_cast(work->data), + [work](MediaKeySessionJsCallback *ptr) { + delete ptr; + delete work; + }); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(work != nullptr, "work is nullptr"); + MediaKeySessionJsCallback *event = reinterpret_cast(work->data); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(event != nullptr, "event is nullptr"); + std::string request = event->callbackName; - napi_value result; - napi_value jsCallback = nullptr; - napi_value retVal; - napi_status state; + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(event->callback != nullptr, "event is nullptr"); + napi_env env = event->callback->env_; + napi_ref callback = event->callback->cb_; - DRM_NAPI_CHECK_AND_RETURN_LOG(callbackMap_.find(event) != callbackMap_.end(), "Not register this callback yet"); - sptr item = callbackMap_[event]; + napi_handle_scope scope = nullptr; + napi_open_handle_scope(env, &scope); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(scope != nullptr, "scope is nullptr"); + DRM_DEBUG_LOG("JsCallBack %{public}s, uv_queue_work_with_qos start", request.c_str()); + do { + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(status != UV_ECANCELED, "%{public}s cancelled", request.c_str()); + napi_value jsCallback = nullptr; + napi_status nstatus = napi_get_reference_value(env, callback, &jsCallback); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(nstatus == napi_ok && jsCallback != nullptr, + "%{public}s get reference value fail", request.c_str()); - DRM_NAPI_CHECK_AND_RETURN_LOG(item != nullptr, "sptr callbackPair is nullptr"); - napi_env env = item->GetEnv(); - napi_ref callbackRef = item->GetCallback(); + // Call back function + if (event->callbackName == "keysChange") { + napi_value statusTable; + napi_value hasNewGoodLicense; + nstatus = NapiParamUtils::SetDrmKeysChangeEventInfo(env, event->keysChangeParame, + statusTable, hasNewGoodLicense); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(nstatus == napi_ok, + "%{public}s fail to create keysession keyschange callback", request.c_str()); + napi_value args[ARGS_TWO] = { statusTable, hasNewGoodLicense }; + napi_value result = nullptr; + nstatus = napi_call_function(env, nullptr, jsCallback, ARGS_TWO, args, &result); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(nstatus == napi_ok, "%{public}s fail to call Interrupt callback", + request.c_str()); + } else { + napi_value args[ARGS_ONE] = { nullptr }; + nstatus = NapiParamUtils::SetDrmEventInfo(env, event->eventParame, args[PARAM0]); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(nstatus == napi_ok && args[PARAM0] != nullptr, + "%{public}s fail to create keysession callback", request.c_str()); + napi_value result = nullptr; + nstatus = napi_call_function(env, nullptr, jsCallback, ARGS_ONE, args, &result); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(nstatus == napi_ok, "%{public}s fail to call Interrupt callback", + request.c_str()); + } + } while (0); + napi_close_handle_scope(env, scope); +} - napi_get_undefined(env, &result); - napi_create_object(env, &result); - napi_value extraValue; - napi_value array = nullptr; - std::string extraData = std::to_string(extra); - napi_create_string_utf8(env, extraData.c_str(), NAPI_AUTO_LENGTH, &extraValue); - state = napi_create_array_with_length(env, data.size(), &array); - DRM_NAPI_CHECK_AND_RETURN_LOG(state == napi_ok, "%{public}s failed to napi_create_array_with_length", - event.c_str()); - for (uint32_t i = 0; i < data.size(); i++) { - napi_value number = nullptr; - (void)napi_create_uint32(env, data[i], &number); - (void)napi_set_element(env, array, i, number); +void MediaKeySessionCallbackNapi::SendEvent(const std::string &event, int32_t extra, const std::vector &data) +{ + std::lock_guard lock(mutex_); + std::unique_ptr cb = std::make_unique(); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(cb != nullptr, "No memory"); + cb->callback = callbackMap_[event]; + cb->callbackName = event; + cb->eventParame.extra = extra; + cb->eventParame.data.assign(data.begin(), data.end()); + return OnJsCallbackInterrupt(cb); +} + +void MediaKeySessionCallbackNapi::OnJsCallbackInterrupt(std::unique_ptr &jsCb) +{ + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(env_, &loop); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(loop != nullptr, "loop nullptr, No memory"); + + uv_work_t *work = new (std::nothrow) uv_work_t; + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(work != nullptr, "work nullptr, No memory"); + + if (jsCb.get() == nullptr) { + DRM_DEBUG_LOG("OnJsCallBackInterrupt: jsCb.get() is null"); + delete work; + return; + } + work->data = reinterpret_cast(jsCb.get()); + + int ret = uv_queue_work_with_qos( + loop, work, [](uv_work_t *work) {}, WorkCallbackInterruptDone, uv_qos_default); + if (ret != 0) { + DRM_DEBUG_LOG("Failed to execute libuv work queue"); + delete work; + } else { + jsCb.release(); } - napi_value args[1] = { nullptr }; - napi_create_object(env, &args[0]); - napi_set_named_property(env, args[0], "info", array); - napi_set_named_property(env, args[0], "extraInfo", extraValue); - napi_get_reference_value(env, callbackRef, &jsCallback); - state = napi_call_function(env, nullptr, jsCallback, ARGS_ONE, args, &retVal); - DRM_NAPI_CHECK_AND_RETURN_LOG(state == napi_ok, "%{public}s failed to napi_call_function", event.c_str()); } void MediaKeySessionCallbackNapi::SendEventKeyChanged( std::map, MediaKeySessionKeyStatus> statusTable, bool hasNewGoodLicense) { - DRM_INFO_LOG("MediaKeySessionCallbackNapi SendEventKeyChanged"); - napi_value result; - napi_value jsCallback = nullptr; - napi_value retVal; - napi_status state; - - DRM_NAPI_CHECK_AND_RETURN_LOG(callbackMap_.find("keysChange") != callbackMap_.end(), - "Not register this callback yet"); - sptr item = callbackMap_["keysChange"]; - - DRM_NAPI_CHECK_AND_RETURN_LOG(item != nullptr, "sptr callbackPair is nullptr"); - napi_env env = item->GetEnv(); - napi_ref callbackRef = item->GetCallback(); - napi_get_undefined(env, &result); - napi_create_object(env, &result); - - uint32_t index = 0; - napi_value map; - napi_create_array_with_length(env, statusTable.size(), &map); - for (auto itemTmp : statusTable) { - napi_value jsObject; - napi_value jsKeyId; - napi_value jsKeyStatus; - napi_create_object(env, &jsObject); - state = napi_create_array_with_length(env, itemTmp.first.size(), &jsKeyId); - DRM_NAPI_CHECK_AND_RETURN_LOG(state == napi_ok, "failed to call napi_create_array_with_length"); - for (uint32_t i = 0; i < itemTmp.first.size(); i++) { - napi_value number = nullptr; - (void)napi_create_uint32(env, itemTmp.first[i], &number); - (void)napi_set_element(env, jsKeyId, i, number); - } - napi_set_named_property(env, jsObject, "keyId", jsKeyId); - std::string value; - switch (itemTmp.second) { - case MEDIA_KEY_SESSION_KEY_STATUS_USABLE: - value = "USABLE"; - break; - case MEDIA_KEY_SESSION_KEY_STATUS_EXPIRED: - value = "EXPIRED"; - break; - case MEDIA_KEY_SESSION_KEY_STATUS_OUTPUT_NOT_ALLOWED: - value = "OUTPUT_NOT_ALLOWED"; - break; - case MEDIA_KEY_SESSION_KEY_STATUS_PENDING: - value = "PENDING"; - break; - case MEDIA_KEY_SESSION_KEY_STATUS_INTERNAL_ERROR: - value = "INTERNAL_ERROR"; - break; - case MEDIA_KEY_SESSION_KEY_STATUS_USABLE_IN_FUTURE: - value = "USABLE_IN_FUTURE"; - break; - default: - value = "Fault Status"; - break; - } - napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &jsKeyStatus); - napi_set_named_property(env, jsObject, "value", jsKeyStatus); - napi_set_element(env, map, index, jsObject); - index++; - } - - napi_value hasNewGoodLicenseValue; - napi_get_boolean(env, hasNewGoodLicense, &hasNewGoodLicenseValue); - - napi_value args[ARGS_TWO] = {map, hasNewGoodLicenseValue}; - napi_get_reference_value(env, callbackRef, &jsCallback); - state = napi_call_function(env, nullptr, jsCallback, ARGS_TWO, args, &retVal); - DRM_NAPI_CHECK_AND_RETURN_LOG(state == napi_ok, "failed to napi_call_function keysChange"); + std::lock_guard lock(mutex_); + std::unique_ptr cb = std::make_unique(); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(cb != nullptr, "No memory"); + const std::string event = "keysChange"; + cb->callback = callbackMap_[event]; + cb->callbackName = event; + cb->keysChangeParame.hasNewGoodLicense = hasNewGoodLicense; + cb->keysChangeParame.statusTable = statusTable; + return OnJsCallbackInterrupt(cb); } -} -} \ No newline at end of file +} // DrmStandardr +} // OHOS \ No newline at end of file diff --git a/frameworks/js/drm_napi/key_session_napi.cpp b/frameworks/js/drm_napi/key_session_napi.cpp index f0e71328..fa578734 100644 --- a/frameworks/js/drm_napi/key_session_napi.cpp +++ b/frameworks/js/drm_napi/key_session_napi.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ #include "ipc_skeleton.h" -#include "drm_napi_utils.h" +#include "napi_param_utils.h" #include "key_session_impl.h" #include "media_key_system_impl.h" #include "key_session_napi.h" @@ -100,17 +100,19 @@ napi_value MediaKeySessionNapi::MediaKeySessionNapiConstructor(napi_env env, nap return result; } obj->keySessionImpl_ = sMediaKeySessionImpl_; - obj->keySessionCallbackNapi_ = new MediaKeySessionCallbackNapi(); + obj->keySessionCallbackNapi_ = new MediaKeySessionCallbackNapi(env); obj->keySessionImpl_->SetCallback(obj->keySessionCallbackNapi_); status = napi_wrap(env, thisVar, reinterpret_cast(obj.get()), MediaKeySessionNapi::MediaKeySessionNapiDestructor, nullptr, nullptr); if (status == napi_ok) { + ObjectRefMap::Insert(obj.get()); obj.release(); const std::string propertyName = "MediaKeySessionNative"; SetMediaKeySessionNativeProperty(env, thisVar, propertyName, sMediaKeySessionImpl_); return thisVar; } else { + ObjectRefMap::Erase(obj.get()); DRM_ERR_LOG("MediaKeySessionNapi Failure wrapping js to native napi"); } } @@ -123,10 +125,7 @@ void MediaKeySessionNapi::MediaKeySessionNapiDestructor(napi_env env, void *nati { DRM_INFO_LOG("MediaKeySessionNapi::MediaKeySessionNapiDestructor enter."); MediaKeySessionNapi *keySessionNapiObj = reinterpret_cast(nativeObject); - if (keySessionNapiObj != nullptr) { - keySessionNapiObj->~MediaKeySessionNapi(); - keySessionNapiObj = nullptr; - } + ObjectRefMap::DecreaseRef(keySessionNapiObj); DRM_INFO_LOG("MediaKeySessionNapi::MediaKeySessionNapiDestructor exit."); } @@ -200,312 +199,200 @@ napi_value MediaKeySessionNapi::Destroy(napi_env env, napi_callback_info info) napi_get_undefined(env, &result); status = napi_unwrap(env, thisVar, reinterpret_cast(&keySessionNapi)); if (status == napi_ok && keySessionNapi != nullptr && keySessionNapi->keySessionImpl_ != nullptr) { - keySessionNapi->keySessionImpl_->Release(); - keySessionNapi->~MediaKeySessionNapi(); - keySessionNapi = nullptr; + int32_t ret = keySessionNapi->keySessionImpl_->Release(); + if (ret != DRM_OK) { + DRM_ERR_LOG("keySessionImpl_ Release call Failed!"); + NapiDrmError::ThrowError(env, "Release failed.", DRM_SERVICE_FATAL_ERROR); + return nullptr; + } } else { DRM_ERR_LOG("MediaKeySessionNapi Release call Failed!"); + NapiDrmError::ThrowError(env, "Release failed.", DRM_UNKNOWN_ERROR); + return nullptr; } DRM_INFO_LOG("MediaKeySessionNapi::Release exit."); return result; } -static napi_value DealMediaKeyRequest(napi_env env, IMediaKeySessionService::MediaKeyRequest &licenseRequest) +bool MediaKeySessionNapi::CheckMediaKeySessionStatus(MediaKeySessionNapi *napi, + std::shared_ptr context) { - const char *requestTypeEnum; - napi_value requestType; - napi_value mData; - napi_value mDefaultURL; - napi_value result = nullptr; - - if (licenseRequest.requestType == IMediaKeySessionService::REQUEST_TYPE_UNKNOWN) { - requestTypeEnum = "MEDIA_KEY_REQUEST_TYPE_UNKNOWN"; - } else if (licenseRequest.requestType == IMediaKeySessionService::REQUEST_TYPE_INITIAL) { - requestTypeEnum = "MEDIA_KEY_REQUEST_TYPE_INITIAL"; - } else if (licenseRequest.requestType == IMediaKeySessionService::REQUEST_TYPE_RENEWAL) { - requestTypeEnum = "MEDIA_KEY_REQUEST_TYPE_RENEWAL"; - } else if (licenseRequest.requestType == IMediaKeySessionService::REQUEST_TYPE_RELEASE) { - requestTypeEnum = "MEDIA_KEY_REQUEST_TYPE_RELEASE"; - } else if (licenseRequest.requestType == IMediaKeySessionService::REQUEST_TYPE_NONE) { - requestTypeEnum = "MEDIA_KEY_REQUEST_TYPE_NONE"; - } else if (licenseRequest.requestType == IMediaKeySessionService::REQUEST_TYPE_UPDATE) { - requestTypeEnum = "MEDIA_KEY_REQUEST_TYPE_UPDATE"; - } else if (licenseRequest.requestType < IMediaKeySessionService::REQUEST_TYPE_UNKNOWN || - licenseRequest.requestType > IMediaKeySessionService::REQUEST_TYPE_UPDATE) { - DRM_ERR_LOG("Do not understand licenseRequest.requestType enum!"); - return result; + DRM_NAPI_CHECK_AND_RETURN_LOG(napi != nullptr, false, "napi object is nullptr."); + if (napi->keySessionImpl_ == nullptr) { + context->SignError(DRM_SERVICE_FATAL_ERROR); + return false; } - - napi_status status = napi_create_string_utf8(env, requestTypeEnum, NAPI_AUTO_LENGTH, &requestType); - if (status != napi_ok) { - DRM_ERR_LOG("requestType error!"); - return result; - } - napi_create_object(env, &result); - napi_set_named_property(env, result, "mediaKeyRequestType", requestType); - - size_t mDataLen = licenseRequest.mData.size(); - NAPI_CALL(env, napi_create_array(env, &mData)); - for (size_t i = 0; i < mDataLen; i++) { - napi_value item; - napi_create_int32(env, licenseRequest.mData[i], &item); - napi_set_element(env, mData, i, item); - } - napi_set_named_property(env, result, "data", mData); - - status = napi_create_string_utf8(env, licenseRequest.mDefaultURL.c_str(), NAPI_AUTO_LENGTH, &mDefaultURL); - if (status != napi_ok) { - DRM_ERR_LOG("mDefaultURL error!"); - return result; - } - napi_set_named_property(env, result, "defaultURL", mDefaultURL); - return result; + return true; } -static napi_status FillTmpOptionalData(napi_env env, napi_value *argv, uint32_t optionalDataCount, - std::map &tmpOptionalData) +bool MediaKeySessionNapi::CheckContextStatus(std::shared_ptr context) { - napi_status status = napi_ok; - if (optionalDataCount > 0) { - for (size_t i = 0; i < optionalDataCount; i++) { - napi_value tmpData; - napi_value tmpName; - napi_value tmpValue; - size_t nameLength = 0; - size_t valueLength = 0; - status = napi_get_element(env, argv[PARAM3], i, &tmpData); - DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "Could not able to read optionalData element!"); - status = napi_get_named_property(env, tmpData, "name", &tmpName); - DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "Could not able to read optionalData property!"); - status = napi_get_named_property(env, tmpData, "value", &tmpValue); - DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "Could not able to read optionalData property!"); - status = napi_get_value_string_utf8(env, tmpName, nullptr, 0, &nameLength); - DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, - "Could not able to transfer optionalData buffer info!"); - status = napi_get_value_string_utf8(env, tmpValue, nullptr, 0, &valueLength); - DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, - "Could not able to transfer optionalData buffer info!"); - std::string name(nameLength, 0); - status = napi_get_value_string_utf8(env, tmpName, &name[0], nameLength + 1, &nameLength); - DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, - "Could not able to transfer optionalData buffer info!"); - std::string value(valueLength, 0); - status = napi_get_value_string_utf8(env, tmpValue, &value[0], valueLength + 1, &valueLength); - DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, - "Could not able to transfer optionalData buffer info!"); - DRM_INFO_LOG("%{public}s: name : %{public}s", __func__, name.c_str()); - DRM_INFO_LOG("%{public}s: value : %{public}s", __func__, value.c_str()); - tmpOptionalData.insert(std::make_pair(name, value)); - } + DRM_NAPI_CHECK_AND_RETURN_LOG(context != nullptr, false, "context object is nullptr."); + if (context->native == nullptr) { + context->SignError(DRM_SERVICE_FATAL_ERROR); + return false; } - return status; + return true; } + napi_value MediaKeySessionNapi::GenerateMediaKeyRequest(napi_env env, napi_callback_info info) { DRM_INFO_LOG("MediaKeySessionNapi::GenerateMediaKeyRequest enter"); + auto context = std::make_shared(); + if (context == nullptr) { + DRM_ERR_LOG("GenerateMediaKeyRequest failed."); + NapiDrmError::ThrowError(env, "GenerateMediaKeyRequest failed.", DRM_UNKNOWN_ERROR); + return NapiParamUtils::GetUndefinedValue(env); + } - size_t argc = ARGS_FOUR; - napi_value argv[ARGS_FOUR] = {0}; - napi_value thisVar = nullptr; - napi_status status; - char buffer[PATH_MAX]; - size_t length = 0; - bool isTypeArray; - void *initData = nullptr; - size_t initDataLen; - size_t offset; - napi_value arraybuffer = nullptr; - napi_typedarray_type type; + auto inputParser = [env, context](size_t argc, napi_value *argv) { + NAPI_CHECK_ARGS_RETURN_VOID(context, argc <= ARGS_FOUR, "invalid arguments", DRM_INVALID_PARAM); + context->mediaKeyRequestInfo.mimeType = NapiParamUtils::GetStringArgument(env, argv[PARAM0]); + context->status = NapiParamUtils::GetValueUint8Array(env, context->mediaKeyRequestInfo.initData, argv[PARAM1]); + NAPI_CHECK_STATUS_RETURN_VOID(context, "generateMediaKeyRequest failed!", DRM_INVALID_PARAM); + int32_t mediaKeyType = 0; + context->status = NapiParamUtils::GetValueInt32(env, mediaKeyType, argv[PARAM2]); + NAPI_CHECK_STATUS_RETURN_VOID(context, "generateMediaKeyRequest failed!", DRM_INVALID_PARAM); + context->mediaKeyRequestInfo.mediaKeyType = (IMediaKeySessionService::MediaKeyType)mediaKeyType; + context->status = + NapiParamUtils::GetValueOptionsData(env, context->mediaKeyRequestInfo.optionalData, argv[PARAM3]); + NAPI_CHECK_STATUS_RETURN_VOID(context, "generateMediaKeyRequest failed!", DRM_INVALID_PARAM); + }; + context->GetCbInfo(env, info, inputParser); - IMediaKeySessionService::MediaKeyRequestInfo licenseRequestInfo; - IMediaKeySessionService::MediaKeyRequest licenseRequest; - MediaKeySessionNapi *keySessionNapi = nullptr; + auto executor = [context]() { + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckContextStatus(context), "context object state is error."); + auto obj = reinterpret_cast(context->native); + ObjectRefMap objectGuard(obj); + auto *napiMediaKeySession = objectGuard.GetPtr(); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckMediaKeySessionStatus(napiMediaKeySession, context), + "MediaKeySession state is error."); + context->intValue = napiMediaKeySession->keySessionImpl_->GenerateMediaKeyRequest(context->mediaKeyRequestInfo, + context->mediaKeyRequest); + if (context->intValue != DRM_OK) { + context->SignError(DRM_SERVICE_FATAL_ERROR); + } + }; - DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); - NAPI_ASSERT(env, argc <= ARGS_FOUR, "requires 4 parameters maximum"); - - DRM_CHECK_AND_RETURN_RET_LOG(napi_get_value_string_utf8(env, argv[PARAM0], buffer, PATH_MAX, &length) == napi_ok, - nullptr, "Could not able to read mimeType argument!"); - napi_is_typedarray(env, argv[PARAM1], &isTypeArray); - DRM_CHECK_AND_RETURN_RET_LOG(isTypeArray, nullptr, "argv[PARAM1] is not array!"); - napi_get_typedarray_info(env, argv[PARAM1], &type, &initDataLen, &initData, &arraybuffer, &offset); - DRM_CHECK_AND_RETURN_RET_LOG(initData != nullptr, nullptr, "napi_get_typedarray_info faild!"); - uint8_t *initDataPtr = reinterpret_cast(initData); - std::vector initDataStr(initDataPtr, initDataPtr + initDataLen); - int32_t licenseType = 0; - status = napi_get_value_int32(env, argv[PARAM2], &licenseType); - DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Could not able to read licenseType argument!"); - // optional data - std::map tmpOptionalData; - uint32_t optionalDataCount = 0; - status = napi_get_array_length(env, argv[PARAM3], &optionalDataCount); - DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Could not able to read optionalData argument!"); - status = FillTmpOptionalData(env, argv, optionalDataCount, tmpOptionalData); - DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "FillTmpOptionalData faild!"); - licenseRequestInfo.mediaKeyType = (IMediaKeySessionService::MediaKeyType)licenseType; - licenseRequestInfo.mimeType = std::string(buffer); - licenseRequestInfo.initData = initDataStr; - licenseRequestInfo.optionalData = tmpOptionalData; - status = napi_unwrap(env, thisVar, reinterpret_cast(&keySessionNapi)); - DRM_CHECK_AND_RETURN_RET_LOG((keySessionNapi != nullptr && keySessionNapi->keySessionImpl_ != nullptr), nullptr, - "MediaKeySessionNapi get keySessionNapi fail!"); - int32_t ret = keySessionNapi->keySessionImpl_->GenerateMediaKeyRequest(licenseRequestInfo, licenseRequest); - DRM_CHECK_AND_RETURN_RET_LOG((ret == DRM_OK), nullptr, "MediaKeySessionNapi GenerateMediaKeyRequest call Failed!"); - napi_value result = DealMediaKeyRequest(env, licenseRequest); - DRM_INFO_LOG("MediaKeySessionNapi::GenerateMediaKeyRequest exit"); - return result; + auto complete = [env, context](napi_value &output) { + NapiParamUtils::SetMediaKeyRequest(env, context->mediaKeyRequest, output); + }; + DRM_INFO_LOG("MediaKeySessionNapi::GenerateMediaKeyRequest exit."); + return NapiAsyncWork::Enqueue(env, context, "GenerateMediaKeyRequest", executor, complete); } napi_value MediaKeySessionNapi::ProcessMediaKeyResponse(napi_env env, napi_callback_info info) { DRM_INFO_LOG("MediaKeySessionNapi::ProcessMediaKeyResponse enter."); - napi_value result = nullptr; - size_t argc = ARGS_ONE; - napi_value argv[ARGS_ONE] = {0}; - napi_value thisVar = nullptr; - napi_status status; - bool isTypeArray; - void *reponseData = nullptr; - size_t reponseDataLen; - size_t offset; - napi_value arraybuffer = nullptr; - napi_typedarray_type type; - std::vector licenseId; - MediaKeySessionNapi *keySessionNapi = nullptr; - - DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); - NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum"); - - napi_is_typedarray(env, argv[PARAM0], &isTypeArray); - if (!isTypeArray) { - DRM_ERR_LOG("reponse is not array! "); - return nullptr; + auto context = std::make_shared(); + if (context == nullptr) { + DRM_ERR_LOG("ProcessMediaKeyResponse failed."); + NapiDrmError::ThrowError(env, "ProcessMediaKeyResponse failed.", DRM_UNKNOWN_ERROR); + return NapiParamUtils::GetUndefinedValue(env); } - napi_get_typedarray_info(env, argv[PARAM0], &type, &reponseDataLen, &reponseData, &arraybuffer, &offset); - if (reponseData == nullptr) { - DRM_ERR_LOG("napi_get_typedarray_info faild! Could not able to read reponseData argument!"); - return nullptr; - } - uint8_t *reponseDataPtr = reinterpret_cast(reponseData); - std::vector licenseResponse(reponseDataPtr, reponseDataPtr + reponseDataLen); - status = napi_unwrap(env, thisVar, reinterpret_cast(&keySessionNapi)); - if (status == napi_ok && keySessionNapi != nullptr && keySessionNapi->keySessionImpl_ != nullptr) { - int32_t ret = keySessionNapi->keySessionImpl_->ProcessMediaKeyResponse(licenseId, licenseResponse); - DRM_CHECK_AND_RETURN_RET_LOG((ret == DRM_OK), nullptr, - "MediaKeySessionNapi ProcessMediaKeyResponse call Failed!"); - size_t licenseIdLen = licenseId.size(); - NAPI_CALL(env, napi_create_array(env, &result)); - for (size_t i = 0; i < licenseIdLen; i++) { - napi_value item; - napi_create_int32(env, licenseId[i], &item); - napi_set_element(env, result, i, item); + auto inputParser = [env, context](size_t argc, napi_value *argv) { + NAPI_CHECK_ARGS_RETURN_VOID(context, argc == ARGS_ONE, "invalid arguments", DRM_INVALID_PARAM); + context->status = NapiParamUtils::GetValueUint8Array(env, context->response, argv[PARAM0]); + NAPI_CHECK_STATUS_RETURN_VOID(context, "ProcessMediaKeyResponse failed!", DRM_INVALID_PARAM); + }; + context->GetCbInfo(env, info, inputParser); + + auto executor = [context]() { + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckContextStatus(context), "context object state is error."); + auto obj = reinterpret_cast(context->native); + ObjectRefMap objectGuard(obj); + auto *napiMediaKeySession = objectGuard.GetPtr(); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckMediaKeySessionStatus(napiMediaKeySession, context), + "MediaKeySession state is error."); + context->intValue = + napiMediaKeySession->keySessionImpl_->ProcessMediaKeyResponse(context->licenseId, context->response); + if (context->intValue != DRM_OK) { + context->SignError(DRM_SERVICE_FATAL_ERROR); } - } else { - DRM_ERR_LOG("MediaKeySessionNapi ProcessMediaKeyResponse call Failed!"); - } + }; + + auto complete = [env, context](napi_value &output) { + NapiParamUtils::SetValueUint8Array(env, context->licenseId, output); + }; DRM_INFO_LOG("MediaKeySessionNapi::ProcessMediaKeyResponse exit."); - return result; + return NapiAsyncWork::Enqueue(env, context, "ProcessMediaKeyResponse", executor, complete); } napi_value MediaKeySessionNapi::GenerateOfflineReleaseRequest(napi_env env, napi_callback_info info) { DRM_INFO_LOG("MediaKeySessionNapi::GenerateOfflineReleaseRequest enter"); - napi_value result = nullptr; - size_t argc = ARGS_ONE; - napi_value argv[ARGS_ONE] = {0}; - napi_value thisVar = nullptr; - napi_status status; - bool isTypeArray; - void *licenseId = nullptr; - size_t licenseIdLen; - size_t offset; - napi_value arraybuffer = nullptr; - napi_typedarray_type type; - std::vector releaseRequest; - MediaKeySessionNapi *keySessionNapi = nullptr; - - DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); - NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum"); - - napi_is_typedarray(env, argv[PARAM0], &isTypeArray); - if (!isTypeArray) { - DRM_ERR_LOG("licenseId is not array!"); - return nullptr; - } - napi_get_typedarray_info(env, argv[PARAM0], &type, &licenseIdLen, &licenseId, &arraybuffer, &offset); - if (licenseId == nullptr) { - DRM_ERR_LOG("napi_get_typedarray_info faild! Could not able to read licenseId argument!"); - return nullptr; - } - uint8_t *licenseIdPtr = reinterpret_cast(licenseId); - std::vector licenseIdVec(licenseIdPtr, licenseIdPtr + licenseIdLen); - - status = napi_unwrap(env, thisVar, reinterpret_cast(&keySessionNapi)); - if (status == napi_ok && keySessionNapi != nullptr && keySessionNapi->keySessionImpl_ != nullptr) { - int32_t ret = keySessionNapi->keySessionImpl_->GenerateOfflineReleaseRequest(licenseIdVec, releaseRequest); - DRM_CHECK_AND_RETURN_RET_LOG((ret == DRM_OK), nullptr, - "MediaKeySessionNapi GenerateOfflineReleaseRequest call Failed!"); - } else { - DRM_ERR_LOG("MediaKeySessionNapi ProcessMediaKeyResponse call Failed!"); - return nullptr; + auto context = std::make_shared(); + if (context == nullptr) { + DRM_ERR_LOG("GenerateOfflineReleaseRequest failed."); + NapiDrmError::ThrowError(env, "GenerateOfflineReleaseRequest failed.", DRM_UNKNOWN_ERROR); + return NapiParamUtils::GetUndefinedValue(env); } - size_t releaseRequestLen = releaseRequest.size(); - NAPI_CALL(env, napi_create_array(env, &result)); - for (size_t i = 0; i < releaseRequestLen; i++) { - napi_value item; - napi_create_int32(env, releaseRequest[i], &item); - napi_set_element(env, result, i, item); - } + auto inputParser = [env, context](size_t argc, napi_value *argv) { + NAPI_CHECK_ARGS_RETURN_VOID(context, argc == ARGS_ONE, "invalid arguments", DRM_INVALID_PARAM); + context->status = NapiParamUtils::GetValueUint8Array(env, context->releaseLicenseId, argv[PARAM0]); + NAPI_CHECK_STATUS_RETURN_VOID(context, "GenerateOfflineReleaseRequest failed", DRM_INVALID_PARAM); + }; + context->GetCbInfo(env, info, inputParser); - DRM_INFO_LOG("MediaKeySessionNapi::GenerateOfflineReleaseRequest exit"); - return result; + auto executor = [context]() { + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckContextStatus(context), "context object state is error."); + auto obj = reinterpret_cast(context->native); + ObjectRefMap objectGuard(obj); + auto *napiMediaKeySession = objectGuard.GetPtr(); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckMediaKeySessionStatus(napiMediaKeySession, context), + "MediaKeySession state is error."); + context->intValue = napiMediaKeySession->keySessionImpl_->GenerateOfflineReleaseRequest( + context->releaseLicenseId, context->releaseRequest); + if (context->intValue != DRM_OK) { + context->SignError(DRM_SERVICE_FATAL_ERROR); + } + }; + + auto complete = [env, context](napi_value &output) { + NapiParamUtils::SetValueUint8Array(env, context->releaseRequest, output); + }; + DRM_INFO_LOG("MediaKeySessionNapi::GenerateOfflineReleaseRequest exit."); + return NapiAsyncWork::Enqueue(env, context, "GenerateOfflineReleaseRequest", executor, complete); } napi_value MediaKeySessionNapi::ProcessOfflineReleaseResponse(napi_env env, napi_callback_info info) { DRM_INFO_LOG("MediaKeySessionNapi::ProcessOfflineReleaseResponse enter."); - napi_value result = nullptr; - size_t argc = ARGS_TWO; - napi_value argv[ARGS_TWO] = {0}; - napi_value thisVar = nullptr; - napi_status status; - bool isTypeArray; - void *licenseId = nullptr; - size_t licenseIdLen; - size_t offset; - napi_value arraybuffer = nullptr; - napi_typedarray_type type; - void *response = nullptr; - size_t responseLen; + auto context = std::make_shared(); + if (context == nullptr) { + DRM_ERR_LOG("ProcessOfflineReleaseResponse failed."); + NapiDrmError::ThrowError(env, "ProcessOfflineReleaseResponse failed.", DRM_UNKNOWN_ERROR); + return NapiParamUtils::GetUndefinedValue(env); + } - DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); - NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum"); + auto inputParser = [env, context](size_t argc, napi_value *argv) { + NAPI_CHECK_ARGS_RETURN_VOID(context, argc == ARGS_TWO, "invalid arguments", DRM_INVALID_PARAM); + context->status = NapiParamUtils::GetValueUint8Array(env, context->releaseResponseLicenseId, argv[PARAM0]); + NAPI_CHECK_STATUS_RETURN_VOID(context, "GetValueUint8Array failed", DRM_INVALID_PARAM); + context->status = NapiParamUtils::GetValueUint8Array(env, context->releaseResponse, argv[PARAM1]); + NAPI_CHECK_STATUS_RETURN_VOID(context, "ProcessOfflineReleaseResponse failed", DRM_INVALID_PARAM); + }; + context->GetCbInfo(env, info, inputParser); - napi_is_typedarray(env, argv[PARAM0], &isTypeArray); - DRM_CHECK_AND_RETURN_RET_LOG(isTypeArray, nullptr, "argv[PARAM0] is not array!"); - napi_get_typedarray_info(env, argv[PARAM0], &type, &licenseIdLen, &licenseId, &arraybuffer, &offset); - DRM_CHECK_AND_RETURN_RET_LOG(licenseId != nullptr, nullptr, "napi_get_typedarray_info faild!"); - uint8_t *licenseIdPtr = reinterpret_cast(licenseId); - std::vector licenseIdVec(licenseIdPtr, licenseIdPtr + licenseIdLen); - napi_is_typedarray(env, argv[PARAM1], &isTypeArray); - DRM_CHECK_AND_RETURN_RET_LOG(isTypeArray, nullptr, "argv[PARAM1] is not array!"); - napi_get_typedarray_info(env, argv[PARAM1], &type, &responseLen, &response, &arraybuffer, &offset); - DRM_CHECK_AND_RETURN_RET_LOG(response != nullptr, nullptr, "napi_get_typedarray_info faild!"); - uint8_t *responsePtr = reinterpret_cast(response); - std::vector responseVec(responsePtr, responsePtr + responseLen); - - MediaKeySessionNapi *keySessionNapi = nullptr; - status = napi_unwrap(env, thisVar, reinterpret_cast(&keySessionNapi)); - DRM_CHECK_AND_RETURN_RET_LOG((keySessionNapi != nullptr && keySessionNapi->keySessionImpl_ != nullptr), nullptr, - "MediaKeySessionNapi get keySessionNapi fail!"); - int32_t ret = keySessionNapi->keySessionImpl_->ProcessOfflineReleaseResponse(licenseIdVec, responseVec); - DRM_CHECK_AND_RETURN_RET_LOG((ret == DRM_OK), nullptr, - "MediaKeySessionNapi ProcessOfflineReleaseResponse call Failed!"); + auto executor = [context]() { + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckContextStatus(context), "context object state is error."); + auto obj = reinterpret_cast(context->native); + ObjectRefMap objectGuard(obj); + auto *napiMediaKeySession = objectGuard.GetPtr(); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckMediaKeySessionStatus(napiMediaKeySession, context), + "MediaKeySession state is error."); + context->intValue = napiMediaKeySession->keySessionImpl_->ProcessOfflineReleaseResponse( + context->releaseResponseLicenseId, context->releaseResponse); + if (context->intValue != DRM_OK) { + context->SignError(DRM_SERVICE_FATAL_ERROR); + } + }; + auto complete = [env, context](napi_value &output) { output = NapiParamUtils::GetUndefinedValue(env); }; DRM_INFO_LOG("MediaKeySessionNapi::ProcessOfflineReleaseResponse exit."); - return result; + return NapiAsyncWork::Enqueue(env, context, "ProcessOfflineReleaseResponse", executor, complete); } static napi_value vectorToJsArray(napi_env env, std::map &licenseStatus) @@ -550,10 +437,14 @@ napi_value MediaKeySessionNapi::CheckMediaKeyStatus(napi_env env, napi_callback_ DRM_CHECK_AND_RETURN_RET_LOG((ret == DRM_OK), nullptr, "MediaKeySessionNapi CheckMediaKeyStatus call Failed!"); } else { DRM_ERR_LOG("MediaKeySessionNapi CheckMediaKeyStatus call Failed!"); + NapiDrmError::ThrowError(env, "MediaKeySessionNapi CheckMediaKeyStatus call Failed!", DRM_UNKNOWN_ERROR); + return nullptr; } if (licenseStatus.size() == 0) { DRM_ERR_LOG("Licence not exist."); + NapiDrmError::ThrowError(env, "MediaKeySessionNapi CheckMediaKeyStatus call Failed!", + DRM_SERVICE_FATAL_ERROR); return nullptr; } result = vectorToJsArray(env, licenseStatus); @@ -564,45 +455,36 @@ napi_value MediaKeySessionNapi::CheckMediaKeyStatus(napi_env env, napi_callback_ napi_value MediaKeySessionNapi::RestoreOfflineMediaKeys(napi_env env, napi_callback_info info) { DRM_INFO_LOG("MediaKeySessionNapi::RestoreOfflineMediaKeys enter."); - napi_value result = nullptr; - size_t argc = ARGS_ONE; - napi_value argv[ARGS_ONE] = {0}; - napi_value thisVar = nullptr; - napi_status status; - bool isTypeArray; - void *licenseId = nullptr; - size_t licenseIdLen; - size_t offset; - napi_value arraybuffer = nullptr; - napi_typedarray_type type; - MediaKeySessionNapi *keySessionNapi = nullptr; - - DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); - NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum"); - - napi_is_typedarray(env, argv[PARAM0], &isTypeArray); - if (!isTypeArray) { - DRM_ERR_LOG("licenseId is not array!"); - return nullptr; - } - napi_get_typedarray_info(env, argv[PARAM0], &type, &licenseIdLen, &licenseId, &arraybuffer, &offset); - if (licenseId == nullptr) { - DRM_ERR_LOG("napi_get_typedarray_info faild! Could not able to read licenseId argument!"); - return nullptr; - } - uint8_t *licenseIdPtr = reinterpret_cast(licenseId); - std::vector licenseIdVec(licenseIdPtr, licenseIdPtr + licenseIdLen); - status = napi_unwrap(env, thisVar, reinterpret_cast(&keySessionNapi)); - if (status == napi_ok && keySessionNapi != nullptr && keySessionNapi->keySessionImpl_ != nullptr) { - int32_t ret = keySessionNapi->keySessionImpl_->RestoreOfflineMediaKeys(licenseIdVec); - DRM_CHECK_AND_RETURN_RET_LOG((ret == DRM_OK), nullptr, - "MediaKeySessionNapi RestoreOfflineMediaKeys call Failed!"); - } else { - DRM_ERR_LOG("MediaKeySessionNapi RestoreOfflineMediaKeys call Failed!"); + auto context = std::make_shared(); + if (context == nullptr) { + DRM_ERR_LOG("RestoreOfflineMediaKeys failed."); + NapiDrmError::ThrowError(env, "RestoreOfflineMediaKeys failed.", DRM_UNKNOWN_ERROR); + return NapiParamUtils::GetUndefinedValue(env); } + auto inputParser = [env, context](size_t argc, napi_value *argv) { + NAPI_CHECK_ARGS_RETURN_VOID(context, argc == ARGS_ONE, "invalid arguments", DRM_INVALID_PARAM); + context->status = NapiParamUtils::GetValueUint8Array(env, context->restoreLicenseId, argv[PARAM0]); + NAPI_CHECK_STATUS_RETURN_VOID(context, "RestoreOfflineMediaKeys failed", DRM_INVALID_PARAM); + }; + context->GetCbInfo(env, info, inputParser); + + auto executor = [context]() { + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckContextStatus(context), "context object state is error."); + auto obj = reinterpret_cast(context->native); + ObjectRefMap objectGuard(obj); + auto *napiMediaKeySession = objectGuard.GetPtr(); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckMediaKeySessionStatus(napiMediaKeySession, context), + "MediaKeySession state is error."); + context->intValue = napiMediaKeySession->keySessionImpl_->RestoreOfflineMediaKeys(context->restoreLicenseId); + if (context->intValue != DRM_OK) { + context->SignError(DRM_SERVICE_FATAL_ERROR); + } + }; + + auto complete = [env, context](napi_value &output) { output = NapiParamUtils::GetUndefinedValue(env); }; DRM_INFO_LOG("MediaKeySessionNapi::RestoreOfflineMediaKeys exit."); - return result; + return NapiAsyncWork::Enqueue(env, context, "RestoreOfflineMediaKeys", executor, complete); } napi_value MediaKeySessionNapi::ClearMediaKeys(napi_env env, napi_callback_info info) @@ -622,9 +504,17 @@ napi_value MediaKeySessionNapi::ClearMediaKeys(napi_env env, napi_callback_info status = napi_unwrap(env, thisVar, reinterpret_cast(&keySessionNapi)); if (status == napi_ok && keySessionNapi != nullptr && keySessionNapi->keySessionImpl_ != nullptr) { int32_t ret = keySessionNapi->keySessionImpl_->ClearMediaKeys(); - DRM_CHECK_AND_RETURN_RET_LOG((ret == DRM_OK), nullptr, "MediaKeySessionNapi ClearMediaKeys call Failed!"); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySessionNapi ClearMediaKeys call Failed!"); + NapiDrmError::ThrowError(env, "MediaKeySessionNapi ClearMediaKeys call Failed!", + DRM_SERVICE_FATAL_ERROR); + return nullptr; + } } else { DRM_ERR_LOG("MediaKeySessionNapi ClearMediaKeys call Failed!"); + NapiDrmError::ThrowError(env, "MediaKeySessionNapi ClearMediaKeys call Failed!", + DRM_UNKNOWN_ERROR); + return nullptr; } DRM_INFO_LOG("MediaKeySessionNapi::ClearMediaKeys exit."); @@ -641,7 +531,11 @@ napi_value MediaKeySessionNapi::RequireSecureDecoderModule(napi_env env, napi_ca DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); napi_get_undefined(env, &result); - NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum"); + if (argc != ARGS_ONE) { + NapiDrmError::ThrowError(env, "RequireSecureDecoderModule faild", DRM_INVALID_PARAM); + DRM_ERR_LOG("invalid arguments."); + return nullptr; + } char mimeTypeBuf[PATH_MAX]; size_t length = 0; @@ -653,12 +547,19 @@ napi_value MediaKeySessionNapi::RequireSecureDecoderModule(napi_env env, napi_ca bool statusValue; MediaKeySessionNapi *keySessionNapi = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&keySessionNapi)); - DRM_CHECK_AND_RETURN_RET_LOG((keySessionNapi != nullptr), nullptr, "MediaKeySessionNapi get keySessionNapi fail!"); + if (keySessionNapi == nullptr) { + DRM_ERR_LOG("napi_unwrapcall Failed!"); + NapiDrmError::ThrowError(env, "napi_unwrapcall failed.", DRM_UNKNOWN_ERROR); + return nullptr; + } DRM_CHECK_AND_RETURN_RET_LOG((keySessionNapi->keySessionImpl_ != nullptr), nullptr, "keySessionImpl_ == nullptr."); int32_t ret = keySessionNapi->keySessionImpl_->RequireSecureDecoderModule(mimeType, &statusValue); - DRM_CHECK_AND_RETURN_RET_LOG((ret == DRM_OK), nullptr, - "MediaKeySessionNapi RequireSecureDecoderModule call Failed!"); + if (ret != DRM_OK) { + DRM_ERR_LOG("keySessionImpl_ RequireSecureDecoderModule call Failed!"); + NapiDrmError::ThrowError(env, "RequireSecureDecoderModule failed.", DRM_SERVICE_FATAL_ERROR); + return nullptr; + } status = napi_get_boolean(env, statusValue, &result); DRM_INFO_LOG("napi_get_boolean call success!,statusValue:%{public}d.", statusValue); @@ -677,15 +578,20 @@ napi_value MediaKeySessionNapi::GetContentProtectionLevel(napi_env env, napi_cal DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); - NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum"); IMediaKeySessionService::ContentProtectionLevel level = (IMediaKeySessionService::ContentProtectionLevel)0; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&keySessionNapi)); if (status == napi_ok && keySessionNapi != nullptr && keySessionNapi->keySessionImpl_ != nullptr) { int32_t ret = keySessionNapi->keySessionImpl_->GetContentProtectionLevel(&level); + if (ret != DRM_OK) { + DRM_ERR_LOG("keySessionImpl_ GetContentProtectionLevel call Failed!"); + NapiDrmError::ThrowError(env, "GetContentProtectionLevel failed.", DRM_SERVICE_FATAL_ERROR); + return nullptr; + } DRM_CHECK_AND_RETURN_RET_LOG((ret == DRM_OK), nullptr, "MediaKeySessionNapi GetContentProtectionLevel call Failed!"); } else { DRM_ERR_LOG("MediaKeySessionNapi GetContentProtectionLevel call Failed!"); + NapiDrmError::ThrowError(env, "GetContentProtectionLevel failed.", DRM_UNKNOWN_ERROR); return nullptr; } @@ -694,7 +600,7 @@ napi_value MediaKeySessionNapi::GetContentProtectionLevel(napi_env env, napi_cal return result; } -void MediaKeySessionNapi::SetEventCallbackReference(const std::string eventType, sptr callbackPair) +void MediaKeySessionNapi::SetEventCallbackReference(const std::string eventType, std::shared_ptr callbackPair) { DRM_INFO_LOG("MediaKeySessionNapi::SetEventCallbackReference"); std::lock_guard lock(mutex_); @@ -728,11 +634,13 @@ napi_value MediaKeySessionNapi::SetEventCallback(napi_env env, napi_callback_inf NAPI_ASSERT(env, argc == ARGS_TWO, "only requires 2 parameters"); if (thisVar == nullptr || argv[PARAM0] == nullptr || argv[PARAM1] == nullptr) { DRM_ERR_LOG("Failed to retrieve arguments in SetEventCallback!"); + NapiDrmError::ThrowError(env, "SetEventCallback faild", DRM_INVALID_PARAM); return result; } napi_valuetype valueType = napi_undefined; if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string || napi_typeof(env, argv[PARAM1], &valueType) != napi_ok || valueType != napi_function) { + NapiDrmError::ThrowError(env, "SetEventCallback faild", DRM_INVALID_PARAM); return result; } @@ -746,11 +654,12 @@ napi_value MediaKeySessionNapi::SetEventCallback(napi_env env, napi_callback_inf napi_create_reference(env, argv[PARAM1], 1, &callbackRef); DRM_INFO_LOG("SetEventCallback event is %{public}s", eventType.c_str()); - sptr callbackPair = new CallBackPair(env, callbackRef); + std::shared_ptr callbackPair = std::make_shared(env, callbackRef); keySessionNapi->SetEventCallbackReference(eventType, callbackPair); DRM_INFO_LOG("MediaKeySessionNapi::SetEventCallback out"); } else { DRM_ERR_LOG("MediaKeySessionNapi SetEventCallback failed!"); + NapiDrmError::ThrowError(env, "MediaKeySessionNapi SetEventCallback failed!", DRM_UNKNOWN_ERROR); } return result; } @@ -767,11 +676,13 @@ napi_value MediaKeySessionNapi::UnsetEventCallback(napi_env env, napi_callback_i NAPI_ASSERT(env, argc == ARGS_ONE, "only requires 1 parameters"); if (thisVar == nullptr || argv[PARAM0] == nullptr) { DRM_ERR_LOG("Failed to retrieve arguments in UnsetEventCallback!"); + NapiDrmError::ThrowError(env, "MediaKeySessionNapi UnsetEventCallback failed!", DRM_INVALID_PARAM); return result; } napi_valuetype valueType = napi_undefined; if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string) { DRM_ERR_LOG("Failed to retrieve reasonable arguments in UnsetEventCallback!"); + NapiDrmError::ThrowError(env, "MediaKeySessionNapi UnsetEventCallback failed!", DRM_INVALID_PARAM); return result; } @@ -786,6 +697,7 @@ napi_value MediaKeySessionNapi::UnsetEventCallback(napi_env env, napi_callback_i DRM_INFO_LOG("MediaKeySessionNapi::UnsetEventCallback out"); } else { DRM_ERR_LOG("MediaKeySessionNapi UnsetEventCallback failed!"); + NapiDrmError::ThrowError(env, "MediaKeySessionNapi UnsetEventCallback failed!", DRM_UNKNOWN_ERROR); } return result; } diff --git a/frameworks/js/drm_napi/media_key_system_callback_napi.cpp b/frameworks/js/drm_napi/media_key_system_callback_napi.cpp index 08b50bae..87ae1baf 100644 --- a/frameworks/js/drm_napi/media_key_system_callback_napi.cpp +++ b/frameworks/js/drm_napi/media_key_system_callback_napi.cpp @@ -14,16 +14,19 @@ */ #include "drm_log.h" #include "drm_error_code.h" -#include "drm_napi_utils.h" #include "media_key_system_callback_napi.h" namespace OHOS { namespace DrmStandard { -MediaKeySystemCallbackNapi::MediaKeySystemCallbackNapi() {} +MediaKeySystemCallbackNapi::MediaKeySystemCallbackNapi(napi_env env) +{ + env_ = env; +} MediaKeySystemCallbackNapi::~MediaKeySystemCallbackNapi() {} -void MediaKeySystemCallbackNapi::SetCallbackReference(const std::string eventType, sptr callbackPair) +void MediaKeySystemCallbackNapi::SetCallbackReference(const std::string eventType, + std::shared_ptr callbackPair) { DRM_INFO_LOG("MediaKeySystemCallbackNapi SetCallbackReference"); std::lock_guard lock(mutex_); @@ -37,47 +40,86 @@ void MediaKeySystemCallbackNapi::ClearCallbackReference(const std::string eventT callbackMap_.erase(eventType); } -void MediaKeySystemCallbackNapi::SendEvent(const std::string event, int32_t extra, - const std::vector data) +void MediaKeySystemCallbackNapi::WorkCallbackInterruptDone(uv_work_t *work, int status) { - DRM_INFO_LOG("MediaKeySystemCallbackNapi SendEvent %{public}s", event.c_str()); - DRM_NAPI_CHECK_AND_RETURN_LOG(!event.empty(), "Service event code error"); + // Js Thread + std::shared_ptr context(static_cast(work->data), + [work](MediaKeySystemJsCallback *ptr) { + delete ptr; + delete work; + }); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(work != nullptr, "work is nullptr"); + MediaKeySystemJsCallback *event = reinterpret_cast(work->data); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(event != nullptr, "event is nullptr"); + std::string request = event->callbackName; - napi_value result; - napi_value jsCallback = nullptr; - napi_value retVal; - napi_status state; + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(event->callback != nullptr, "event is nullptr"); + napi_env env = event->callback->env_; + napi_ref callback = event->callback->cb_; - DRM_NAPI_CHECK_AND_RETURN_LOG(callbackMap_.find(event) != callbackMap_.end(), "Not register this callback yet"); - sptr item = callbackMap_[event]; + napi_handle_scope scope = nullptr; + napi_open_handle_scope(env, &scope); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(scope != nullptr, "scope is nullptr"); + DRM_DEBUG_LOG("JsCallBack %{public}s, uv_queue_work_with_qos start", request.c_str()); + do { + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(status != UV_ECANCELED, "%{public}s cancelled", request.c_str()); - DRM_NAPI_CHECK_AND_RETURN_LOG(item != nullptr, "sptr callbackPair is nullptr"); - napi_env env = item->GetEnv(); - napi_ref callbackRef = item->GetCallback(); + napi_value jsCallback = nullptr; + napi_status nstatus = napi_get_reference_value(env, callback, &jsCallback); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(nstatus == napi_ok && jsCallback != nullptr, + "%{public}s get reference value fail", request.c_str()); - napi_get_undefined(env, &result); - napi_create_object(env, &result); + // Call back function + napi_value args[ARGS_ONE] = { nullptr }; + nstatus = NapiParamUtils::SetDrmEventInfo(env, event->eventParame, args[PARAM0]); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(nstatus == napi_ok && args[PARAM0] != nullptr, + "%{public}s fail to create keysystem callback", request.c_str()); - napi_value extraValue; - std::string extraData = std::to_string(extra); - napi_create_string_utf8(env, extraData.c_str(), NAPI_AUTO_LENGTH, &extraValue); - napi_value array = nullptr; - state = napi_create_array_with_length(env, data.size(), &array); - DRM_NAPI_CHECK_AND_RETURN_LOG(state == napi_ok, - "%{public}s failed to napi_create_array_with_length", event.c_str()); - for (uint32_t i = 0; i < data.size(); i++) { - napi_value number = nullptr; - (void)napi_create_uint32(env, data[i], &number); - (void)napi_set_element(env, array, i, number); + const size_t argCount = ARGS_ONE; + napi_value result = nullptr; + nstatus = napi_call_function(env, nullptr, jsCallback, argCount, args, &result); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(nstatus == napi_ok, "%{public}s fail to call Interrupt callback", + request.c_str()); + } while (0); + napi_close_handle_scope(env, scope); +} + +void MediaKeySystemCallbackNapi::SendEvent(const std::string &event, int32_t extra, const std::vector &data) +{ + std::lock_guard lock(mutex_); + std::unique_ptr cb = std::make_unique(); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(cb != nullptr, "No memory"); + cb->callback = callbackMap_[event]; + cb->callbackName = event; + cb->eventParame.extra = extra; + cb->eventParame.data.assign(data.begin(), data.end()); + return OnJsCallbackInterrupt(cb); +} + +void MediaKeySystemCallbackNapi::OnJsCallbackInterrupt(std::unique_ptr &jsCb) +{ + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(env_, &loop); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(loop != nullptr, "loop nullptr, No memory"); + + uv_work_t *work = new (std::nothrow) uv_work_t; + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(work != nullptr, "work nullptr, No memory"); + + if (jsCb.get() == nullptr) { + DRM_DEBUG_LOG("OnJsCallBackInterrupt: jsCb.get() is null"); + delete work; + return; + } + work->data = reinterpret_cast(jsCb.get()); + + int ret = uv_queue_work_with_qos( + loop, work, [](uv_work_t *work) {}, WorkCallbackInterruptDone, uv_qos_default); + if (ret != 0) { + DRM_DEBUG_LOG("Failed to execute libuv work queue"); + delete work; + } else { + jsCb.release(); } - napi_value args[1] = { nullptr }; - napi_create_object(env, &args[0]); - napi_set_named_property(env, args[0], "info", array); - napi_set_named_property(env, args[0], "extraInfo", extraValue); - napi_get_reference_value(env, callbackRef, &jsCallback); - state = napi_call_function(env, nullptr, jsCallback, ARGS_ONE, args, &retVal); - DRM_NAPI_CHECK_AND_RETURN_LOG(state == napi_ok, - "%{public}s failed to napi_call_function", event.c_str()); } } // namespace DrmStandard } // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/drm_napi/media_key_system_napi.cpp b/frameworks/js/drm_napi/media_key_system_napi.cpp index aed65f16..630b80ae 100644 --- a/frameworks/js/drm_napi/media_key_system_napi.cpp +++ b/frameworks/js/drm_napi/media_key_system_napi.cpp @@ -12,9 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "drm_napi_utils.h" #include "key_session_napi.h" #include "media_key_system_napi.h" +#include "napi_param_utils.h" + namespace OHOS { namespace DrmStandard { thread_local napi_ref MediaKeySystemNapi::sConstructor_ = nullptr; @@ -100,15 +101,16 @@ napi_value MediaKeySystemNapi::MediaKeySystemNapiConstructor(napi_env env, napi_ return result; } obj->mediaKeySystemImpl_ = MediaKeySystemNapi::sMediaKeySystemImpl_; - obj->mediaKeySystemCallbackNapi_ = new (std::nothrow) MediaKeySystemCallbackNapi(); + obj->mediaKeySystemCallbackNapi_ = new (std::nothrow) MediaKeySystemCallbackNapi(env); obj->mediaKeySystemImpl_->SetCallback(obj->mediaKeySystemCallbackNapi_); - status = napi_wrap(env, jsThis, reinterpret_cast(obj.get()), MediaKeySystemNapi::MediaKeySystemNapiDestructor, nullptr, nullptr); if (status == napi_ok) { + ObjectRefMap::Insert(obj.get()); obj.release(); return jsThis; } else { + ObjectRefMap::Erase(obj.get()); DRM_ERR_LOG("Failure wrapping js to native napi"); } DRM_ERR_LOG("will call IsMediaKeySystemSupported"); @@ -140,25 +142,28 @@ napi_value MediaKeySystemNapi::CreateMediaKeySystemInstance(napi_env env, napi_c size_t uuidBufferLen = 0; status = napi_get_value_string_utf8(env, argv[PARAM0], uuidBuffer, PATH_MAX, &uuidBufferLen); if (status != napi_ok) { + NapiDrmError::ThrowError(env, "CreateMediaKeySystemInstance faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("Could not able to read uuid argument!"); return nullptr; } uuid = std::string(uuidBuffer); - int32_t retCode = MediaKeySystemFactoryImpl::GetInstance()->CreateMediaKeySystem(uuid, + int32_t ret = MediaKeySystemFactoryImpl::GetInstance()->CreateMediaKeySystem(uuid, &MediaKeySystemNapi::sMediaKeySystemImpl_); - if (retCode != DRM_OK || MediaKeySystemNapi::sMediaKeySystemImpl_ == nullptr) { - DRM_ERR_LOG("MediaKeySystemNapi sMediaKeySystemImpl_ get failed!!!"); + if (ret != DRM_OK) { + NapiDrmError::ThrowError(env, "CreateMediaKeySystemInstance faild.", ret); + DRM_ERR_LOG("CreateMediaKeySystem failed!"); return nullptr; } status = napi_new_instance(env, ctor, 0, nullptr, &result); MediaKeySystemNapi::sMediaKeySystemImpl_ = nullptr; if (status == napi_ok) { - DRM_ERR_LOG("CreateMediaKeySystemInstance 164"); + DRM_INFO_LOG("MediaKeySystemNapi::CreateMediaKeySystemInstance exit."); return result; } else { DRM_ERR_LOG("New instance could not be obtained"); } } + NapiDrmError::ThrowError(env, "CreateMediaKeySystem faild.", DRM_UNKNOWN_ERROR); napi_get_undefined(env, &result); DRM_INFO_LOG("MediaKeySystemNapi::CreateMediaKeySystemInstance exit."); return result; @@ -168,9 +173,7 @@ void MediaKeySystemNapi::MediaKeySystemNapiDestructor(napi_env env, void *native { DRM_INFO_LOG("MediaKeySystemNapi::MediaKeySystemNapiDestructor enter."); MediaKeySystemNapi *mediaKeySystemNapi = reinterpret_cast(nativeObject); - if (mediaKeySystemNapi != nullptr) { - mediaKeySystemNapi->~MediaKeySystemNapi(); - } + ObjectRefMap::DecreaseRef(mediaKeySystemNapi); DRM_INFO_LOG("MediaKeySystemNapi::MediaKeySystemNapiDestructor exit."); } @@ -191,9 +194,14 @@ napi_value MediaKeySystemNapi::IsMediaKeySystemSupported(napi_env env, napi_call } std::string uuid = std::string(buffer); if (uuid.length() == 0 || uuid.length() > MAX_STRING_SIZE) { + NapiDrmError::ThrowError(env, "IsMediaKeySystemSupported faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("uuid lenth is not able to zero or more 256!"); return nullptr; } + if (MediaKeySystemFactoryImpl::GetInstance() == nullptr) { + NapiDrmError::ThrowError(env, "IsMediaKeySystemSupported faild.", DRM_SERVICE_FATAL_ERROR); + return nullptr; + } if (argc == ARGS_ONE) { bool isSurpportted = MediaKeySystemFactoryImpl::GetInstance()->IsMediaKeySystemSupported(uuid); napi_get_boolean(env, isSurpportted, &result); @@ -201,6 +209,7 @@ napi_value MediaKeySystemNapi::IsMediaKeySystemSupported(napi_env env, napi_call } buffer[0] = '\0'; if (napi_get_value_string_utf8(env, argv[PARAM1], buffer, PATH_MAX, &length) != napi_ok) { + NapiDrmError::ThrowError(env, "IsMediaKeySystemSupported faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("Could not able to read mimeType argument!"); return nullptr; } @@ -212,15 +221,16 @@ napi_value MediaKeySystemNapi::IsMediaKeySystemSupported(napi_env env, napi_call } buffer[0] = '\0'; - int32_t jsContentProtectionLevel = -1; + int32_t jsContentProtectionLevel = DRM_ERROR; if (napi_get_value_int32(env, argv[PARAM2], &jsContentProtectionLevel) != napi_ok) { DRM_ERR_LOG("Could not able to read securityLevel argument!"); return nullptr; } IMediaKeySessionService::ContentProtectionLevel securityLevel = (IMediaKeySessionService::ContentProtectionLevel)jsContentProtectionLevel; - if ((securityLevel < IMediaKeySessionService::CONTENT_PROTECTION_LEVEL_UNKNOWN) || + if ((securityLevel <= IMediaKeySessionService::CONTENT_PROTECTION_LEVEL_UNKNOWN) || (securityLevel >= IMediaKeySessionService::CONTENT_PROTECTION_LEVEL_MAX)) { + NapiDrmError::ThrowError(env, "IsMediaKeySystemSupported faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("jsContentProtectionLevel is invalid"); return nullptr; } @@ -232,6 +242,7 @@ napi_value MediaKeySystemNapi::IsMediaKeySystemSupported(napi_env env, napi_call DRM_INFO_LOG("MediaKeySystemNapi::IsMediaKeySystemSupported exit."); return result; } + NapiDrmError::ThrowError(env, "IsMediaKeySystemSupported faild.", DRM_INVALID_PARAM); DRM_INFO_LOG("MediaKeySystemNapi::IsMediaKeySystemSupported exit."); return nullptr; } @@ -254,19 +265,13 @@ napi_value MediaKeySystemNapi::CreateMediaKeySession(napi_env env, napi_callback } else { DRM_CHECK_AND_RETURN_RET_LOG(napi_get_value_int32(env, argv[PARAM0], &jsContentProtectionLevel) == napi_ok, nullptr, "MediaKeySystemNapi napi get jsContentProtectionLevel failure!"); - IMediaKeySessionService::ContentProtectionLevel securityLevel = - (IMediaKeySessionService::ContentProtectionLevel)jsContentProtectionLevel; - if ((securityLevel < IMediaKeySessionService::CONTENT_PROTECTION_LEVEL_UNKNOWN) || - (securityLevel > IMediaKeySessionService::CONTENT_PROTECTION_LEVEL_MAX)) { - DRM_ERR_LOG("ContentProtectionLevel is invalid"); - return nullptr; - } } napi_get_undefined(env, &result); IMediaKeySessionService::ContentProtectionLevel securityLevel = static_cast(jsContentProtectionLevel); - if (securityLevel < IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_UNKNOWN || - securityLevel > IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_MAX) { + if (securityLevel <= IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_UNKNOWN || + securityLevel >= IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_MAX) { + NapiDrmError::ThrowError(env, "CreateMediaKeySession faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("securityLevel is error!!!"); return nullptr; } @@ -274,7 +279,8 @@ napi_value MediaKeySystemNapi::CreateMediaKeySession(napi_env env, napi_callback if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) { int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->CreateMediaKeySession( (IMediaKeySessionService::ContentProtectionLevel)securityLevel, &keySessionImpl); - if (ret != DRM_OK || keySessionImpl == nullptr) { + if (ret != DRM_OK) { + NapiDrmError::ThrowError(env, "CreateMediaKeySession failed", ret); DRM_ERR_LOG("MediaKeySystemNapi::CreateMediaKeySession get failed!!!"); return nullptr; } @@ -308,6 +314,7 @@ napi_value MediaKeySystemNapi::SetConfigurationString(napi_env env, napi_callbac status = napi_get_value_string_utf8(env, argv[PARAM0], nameBuffer, PATH_MAX, &nameBufferLen); if (status != napi_ok) { + NapiDrmError::ThrowError(env, "SetConfigurationString faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("Could not able to read name argument!"); return nullptr; } @@ -315,11 +322,13 @@ napi_value MediaKeySystemNapi::SetConfigurationString(napi_env env, napi_callbac status = napi_get_value_string_utf8(env, argv[PARAM1], valueBuffer, PATH_MAX, &valueBufferLen); if (status != napi_ok) { DRM_ERR_LOG("Could not able to read value argument!"); + NapiDrmError::ThrowError(env, "SetConfigurationString faild.", DRM_INVALID_PARAM); return nullptr; } value = std::string(valueBuffer); if (value.length() == 0) { DRM_ERR_LOG("String Parameter length cannot be zero!"); + NapiDrmError::ThrowError(env, "SetConfigurationString faild.", DRM_INVALID_PARAM); return nullptr; } status = napi_unwrap(env, thisVar, reinterpret_cast(&mediaKeySystemNapi)); @@ -327,10 +336,12 @@ napi_value MediaKeySystemNapi::SetConfigurationString(napi_env env, napi_callbac int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->SetConfigurationString(name, value); if (ret != napi_ok) { DRM_ERR_LOG("napi SetConfiguration faild!"); + NapiDrmError::ThrowError(env, "SetConfigurationString faild.", DRM_SERVICE_FATAL_ERROR); return nullptr; } } else { DRM_ERR_LOG("mediaKeySystemNapi SetConfiguration call Failed!"); + NapiDrmError::ThrowError(env, "SetConfigurationString faild.", DRM_UNKNOWN_ERROR); return nullptr; } @@ -354,16 +365,22 @@ napi_value MediaKeySystemNapi::GetConfigurationString(napi_env env, napi_callbac DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum"); - napi_get_value_string_utf8(env, argv[PARAM0], nameStr, PATH_MAX, &nameStrLength); + status = napi_get_value_string_utf8(env, argv[PARAM0], nameStr, PATH_MAX, &nameStrLength); + if (status != napi_ok) { + NapiDrmError::ThrowError(env, "GetConfigurationString faild.", DRM_INVALID_PARAM); + return nullptr; + } std::string name = std::string(nameStr); status = napi_unwrap(env, thisVar, reinterpret_cast(&mediaKeySystemNapi)); if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) { int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetConfigurationString(name, value); if (ret != napi_ok) { + NapiDrmError::ThrowError(env, "GetConfigurationString faild.", DRM_SERVICE_FATAL_ERROR); DRM_ERR_LOG("napi GetConfiguration faild!"); return nullptr; } } else { + NapiDrmError::ThrowError(env, "GetConfigurationString faild.", DRM_UNKNOWN_ERROR); DRM_ERR_LOG("mediaKeySystemNapi GetConfigurationString Failed!"); return nullptr; } @@ -398,17 +415,20 @@ napi_value MediaKeySystemNapi::SetConfigurationByteArray(napi_env env, napi_call status = napi_get_value_string_utf8(env, argv[PARAM0], nameBuffer, PATH_MAX, &nameBufferLen); if (status != napi_ok) { + NapiDrmError::ThrowError(env, "SetConfigurationByteArray faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("Could not able to read name argument!"); return nullptr; } name = std::string(nameBuffer); napi_is_typedarray(env, argv[PARAM1], &isTypeArray); if (!isTypeArray) { + NapiDrmError::ThrowError(env, "SetConfigurationByteArray faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("argv[PARAM1] value is not array!"); return nullptr; } napi_get_typedarray_info(env, argv[PARAM1], &type, &valueDataLen, &valueData, &arraybuffer, &offset); if (valueData == nullptr) { + NapiDrmError::ThrowError(env, "SetConfigurationByteArray faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("napi_get_typedarray_info faild!"); return nullptr; } @@ -418,10 +438,12 @@ napi_value MediaKeySystemNapi::SetConfigurationByteArray(napi_env env, napi_call if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) { int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->SetConfigurationByteArray(name, value); if (ret != napi_ok) { + NapiDrmError::ThrowError(env, "SetConfigurationByteArray faild.", DRM_SERVICE_FATAL_ERROR); DRM_ERR_LOG("napi SetConfigurationByteArray faild!"); return nullptr; } } else { + NapiDrmError::ThrowError(env, "SetConfigurationByteArray faild.", DRM_UNKNOWN_ERROR); DRM_ERR_LOG("mediaKeySystemNapi SetConfigurationByteArray call Failed!"); return nullptr; } @@ -446,16 +468,23 @@ napi_value MediaKeySystemNapi::GetConfigurationByteArray(napi_env env, napi_call DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum"); - napi_get_value_string_utf8(env, argv[PARAM0], nameStr, PATH_MAX, &nameStrLength); + status = napi_get_value_string_utf8(env, argv[PARAM0], nameStr, PATH_MAX, &nameStrLength); + if (status != napi_ok) { + NapiDrmError::ThrowError(env, "GetConfigurationByteArray faild.", DRM_INVALID_PARAM); + DRM_ERR_LOG("Could not able to read name argument!"); + return nullptr; + } std::string name = std::string(nameStr); status = napi_unwrap(env, thisVar, reinterpret_cast(&mediaKeySystemNapi)); if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) { int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetConfigurationByteArray(name, value); if (ret != napi_ok) { + NapiDrmError::ThrowError(env, "GetConfigurationByteArray faild.", DRM_SERVICE_FATAL_ERROR); DRM_ERR_LOG("napi GetConfiguration faild!"); return nullptr; } } else { + NapiDrmError::ThrowError(env, "GetConfigurationByteArray faild.", DRM_UNKNOWN_ERROR); DRM_ERR_LOG("mediaKeySystemNapi GetConfigurationByteArray Failed!"); return nullptr; } @@ -489,10 +518,12 @@ napi_value MediaKeySystemNapi::GetMaxContentProtectionLevel(napi_env env, napi_c if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) { int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetMaxContentProtectionLevel(&level); if (ret != napi_ok) { + NapiDrmError::ThrowError(env, "GetMaxContentProtectionLevel faild.", DRM_SERVICE_FATAL_ERROR); DRM_ERR_LOG("mediaKeySystemImpl_->GetCertificateStatus faild!"); return nullptr; } } else { + NapiDrmError::ThrowError(env, "GetMaxContentProtectionLevel faild.", DRM_UNKNOWN_ERROR); DRM_ERR_LOG("MediaKeySystemNapi GetMaxContentProtectionLevel call Failed!"); return nullptr; } @@ -502,93 +533,94 @@ napi_value MediaKeySystemNapi::GetMaxContentProtectionLevel(napi_env env, napi_c return result; } +bool MediaKeySystemNapi::CheckMediaKeySystemStatus(MediaKeySystemNapi *napi, + std::shared_ptr context) +{ + DRM_NAPI_CHECK_AND_RETURN_LOG(napi != nullptr, false, "napi object is nullptr."); + if (napi->mediaKeySystemImpl_ == nullptr) { + context->SignError(DRM_SERVICE_FATAL_ERROR); + return false; + } + return true; +} + +bool MediaKeySystemNapi::CheckContextStatus(std::shared_ptr context) +{ + DRM_NAPI_CHECK_AND_RETURN_LOG(context != nullptr, false, "context object is nullptr."); + if (context->native == nullptr) { + context->SignError(DRM_SERVICE_FATAL_ERROR); + return false; + } + return true; +} + napi_value MediaKeySystemNapi::GenerateKeySystemRequest(napi_env env, napi_callback_info info) { DRM_INFO_LOG("MediaKeySystemNapi::GenerateKeySystemRequest enter"); - napi_value result = nullptr; - napi_value thisVar = nullptr; - napi_status status; - size_t argc = ARGS_ZERO; - napi_value argv[ARGS_ZERO]; - std::vector request; - std::string defaultUrl; - napi_value mDefaultURL; - napi_value mData; + auto context = std::make_shared(); + if (context == nullptr) { + DRM_ERR_LOG("GenerateKeySystemRequest failed."); + NapiDrmError::ThrowError(env, "GenerateKeySystemRequest failed.", DRM_UNKNOWN_ERROR); + return NapiParamUtils::GetUndefinedValue(env); + } - MediaKeySystemNapi *mediaKeySystemNapi = nullptr; - DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); - status = napi_unwrap(env, thisVar, reinterpret_cast(&mediaKeySystemNapi)); - if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) { - int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GenerateKeySystemRequest(request, defaultUrl); - if (ret != napi_ok) { - DRM_ERR_LOG("napi GenerateKeySystemRequest faild!"); - return nullptr; + context->GetCbInfo(env, info); + + auto executor = [context]() { + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckContextStatus(context), "context object state is error."); + auto obj = reinterpret_cast(context->native); + ObjectRefMap objectGuard(obj); + auto *napiMediaKeySystem = objectGuard.GetPtr(); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckMediaKeySystemStatus(napiMediaKeySystem, context), + "context object state is error."); + context->intValue = napiMediaKeySystem->mediaKeySystemImpl_->GenerateKeySystemRequest( + context->provisionRequest.data, context->provisionRequest.defaultURL); + if (context->intValue != 0) { + context->SignError(DRM_SERVICE_FATAL_ERROR); } - } else { - DRM_ERR_LOG("mediaKeySystemNapi GenerateKeySystemRequest call Failed!"); - return nullptr; - } - - NAPI_CALL(env, napi_create_object(env, &result)); - size_t requestLen = request.size(); - NAPI_CALL(env, napi_create_array(env, &mData)); - for (size_t i = 0; i < requestLen; i++) { - napi_value item; - napi_create_int32(env, request[i], &item); - napi_set_element(env, mData, i, item); - } - NAPI_CALL(env, napi_create_string_utf8(env, defaultUrl.c_str(), NAPI_AUTO_LENGTH, &mDefaultURL)); - NAPI_CALL(env, napi_set_named_property(env, result, "defaultURL", mDefaultURL)); - NAPI_CALL(env, napi_set_named_property(env, result, "data", mData)); + }; + auto complete = [env, context](napi_value &output) { + NapiParamUtils::SetProvisionRequest(env, context->provisionRequest, output); + }; DRM_INFO_LOG("MediaKeySystemNapi::GenerateKeySystemRequest exit"); - return result; + return NapiAsyncWork::Enqueue(env, context, "GenerateKeySystemRequest", executor, complete); } napi_value MediaKeySystemNapi::ProcessKeySystemResponse(napi_env env, napi_callback_info info) { DRM_INFO_LOG("MediaKeySystemNapi::ProcessKeySystemResponse enter."); - napi_value result = nullptr; - size_t argc = ARGS_TWO; - napi_value argv[ARGS_TWO] = {0}; - napi_value thisVar = nullptr; - napi_status status; - bool isTypeArray; - void *reponseData = nullptr; - size_t reponseDataLen; - size_t offset; - napi_value arraybuffer = nullptr; - napi_typedarray_type type; - MediaKeySystemNapi *mediaKeySystemNapi = nullptr; + auto context = std::make_shared(); + if (context == nullptr) { + DRM_ERR_LOG("ProcessKeySystemResponse failed."); + NapiDrmError::ThrowError(env, "ProcessKeySystemResponse failed.", DRM_UNKNOWN_ERROR); + return NapiParamUtils::GetUndefinedValue(env); + } - DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); - NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum"); - napi_is_typedarray(env, argv[PARAM0], &isTypeArray); - if (!isTypeArray) { - DRM_ERR_LOG("argv[PARAM0] reponse is not array!"); - return nullptr; - } - napi_get_typedarray_info(env, argv[PARAM0], &type, &reponseDataLen, &reponseData, &arraybuffer, &offset); - if (reponseData == nullptr) { - DRM_ERR_LOG("napi_get_typedarray_info faild!"); - return nullptr; - } - uint8_t *reponseDataPtr = reinterpret_cast(reponseData); - std::vector keySystemResponse(reponseDataPtr, reponseDataPtr + reponseDataLen); - status = napi_unwrap(env, thisVar, reinterpret_cast(&mediaKeySystemNapi)); - if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) { - int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->ProcessKeySystemResponse(keySystemResponse); - if (ret != napi_ok) { - DRM_ERR_LOG("napi ProcessKeySystemResponse faild!"); - return nullptr; + auto inputParser = [env, context](size_t argc, napi_value *argv) { + NAPI_CHECK_ARGS_RETURN_VOID(context, argc == ARGS_ONE, "invalid arguments", DRM_INVALID_PARAM); + context->status = NapiParamUtils::GetValueUint8Array(env, context->response, argv[PARAM0]); + NAPI_CHECK_STATUS_RETURN_VOID(context, "ProcessKeySystemResponse failed", DRM_INVALID_PARAM); + }; + + context->GetCbInfo(env, info, inputParser); + + auto executor = [context]() { + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckContextStatus(context), "context object state is error."); + auto obj = reinterpret_cast(context->native); + ObjectRefMap objectGuard(obj); + auto *napiMediaKeySystem = objectGuard.GetPtr(); + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(CheckMediaKeySystemStatus(napiMediaKeySystem, context), + "context object state is error."); + context->intValue = napiMediaKeySystem->mediaKeySystemImpl_->ProcessKeySystemResponse(context->response); + if (context->intValue != DRM_OK) { + context->SignError(DRM_SERVICE_FATAL_ERROR); } - } else { - DRM_ERR_LOG("mediaKeySystemNapi ProcessKeySystemResponse call Failed!"); - return nullptr; - } + }; + auto complete = [env](napi_value &output) { output = NapiParamUtils::GetUndefinedValue(env); }; DRM_INFO_LOG("MediaKeySystemNapi::ProcessKeySystemResponse exit."); - return result; + return NapiAsyncWork::Enqueue(env, context, "ProcessKeySystemResponse", executor, complete); } static napi_value vectorToJsArray(napi_env env, std::vector &metrics) @@ -628,10 +660,12 @@ napi_value MediaKeySystemNapi::GetStatistics(napi_env env, napi_callback_info in if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) { int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetStatistics(metrics); if (ret != napi_ok) { + NapiDrmError::ThrowError(env, "GetStatistics faild.", DRM_SERVICE_FATAL_ERROR); DRM_ERR_LOG("mediaKeySystemImpl_->GetStatistics faild!"); return nullptr; } } else { + NapiDrmError::ThrowError(env, "GetStatistics faild.", DRM_UNKNOWN_ERROR); DRM_ERR_LOG("mediaKeySystemNapi GetStatistics Failed!"); return nullptr; } @@ -656,10 +690,12 @@ napi_value MediaKeySystemNapi::GetCertificateStatus(napi_env env, napi_callback_ if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) { int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetCertificateStatus(&certStatus); if (ret != napi_ok) { + NapiDrmError::ThrowError(env, "GetCertificateStatus faild.", DRM_SERVICE_FATAL_ERROR); DRM_ERR_LOG("mediaKeySystemImpl_->GetCertificateStatus faild!"); return nullptr; } } else { + NapiDrmError::ThrowError(env, "GetCertificateStatus faild.", DRM_UNKNOWN_ERROR); DRM_ERR_LOG("mediaKeySystemNapi GetCertificateStatus Failed!"); return nullptr; } @@ -726,11 +762,14 @@ napi_value MediaKeySystemNapi::GetOfflineMediaKeyIds(napi_env env, napi_callback if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) { int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetOfflineMediaKeyIds(licenseIds); if (ret != napi_ok) { + NapiDrmError::ThrowError(env, "GetOfflineMediaKeyIds faild.", DRM_SERVICE_FATAL_ERROR); DRM_ERR_LOG("napi GetOfflineMediaKeyIds faild!"); return nullptr; } } else { + NapiDrmError::ThrowError(env, "GetOfflineMediaKeyIds faild.", DRM_UNKNOWN_ERROR); DRM_ERR_LOG("MediaKeySystemNapi GetOfflineMediaKeyIds call Failed!"); + return nullptr; } result = vectorToJs2DArray(env, licenseIds); @@ -758,11 +797,13 @@ napi_value MediaKeySystemNapi::GetOfflineMediaKeyStatus(napi_env env, napi_callb NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum"); napi_is_typedarray(env, argv[PARAM0], &isTypeArray); if (!isTypeArray) { + NapiDrmError::ThrowError(env, "GetOfflineMediaKeyStatus faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("argv[PARAM0] is not array!"); return nullptr; } napi_get_typedarray_info(env, argv[PARAM0], &type, &licenseIdLen, &licenseId, &arraybuffer, &offset); if (licenseId == nullptr) { + NapiDrmError::ThrowError(env, "GetOfflineMediaKeyStatus faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("napi_get_typedarray_info faild!"); return nullptr; } @@ -775,10 +816,12 @@ napi_value MediaKeySystemNapi::GetOfflineMediaKeyStatus(napi_env env, napi_callb int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->GetOfflineMediaKeyStatus(licenseIdVec, offlineMediaKeyStatus); if (ret != napi_ok) { + NapiDrmError::ThrowError(env, "GetOfflineMediaKeyStatus faild.", DRM_SERVICE_FATAL_ERROR); DRM_ERR_LOG("napi GetOfflineMediaKeyStatus faild!"); return nullptr; } } else { + NapiDrmError::ThrowError(env, "GetOfflineMediaKeyStatus faild.", DRM_UNKNOWN_ERROR); DRM_ERR_LOG("MediaKeySystemNapi GetOfflineMediaKeyStatus call Failed!"); return nullptr; } @@ -808,6 +851,7 @@ napi_value MediaKeySystemNapi::ClearOfflineMediaKeys(napi_env env, napi_callback NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 2 parameters maximum"); napi_is_typedarray(env, argv[PARAM0], &isTypeArray); if (!isTypeArray) { + NapiDrmError::ThrowError(env, "ClearOfflineMediaKeys faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("argv[PARAM0] is not array!"); return nullptr; } @@ -823,10 +867,13 @@ napi_value MediaKeySystemNapi::ClearOfflineMediaKeys(napi_env env, napi_callback int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->ClearOfflineMediaKeys(licenseIdVec); if (ret != napi_ok) { DRM_ERR_LOG("napi ClearOfflineMediaKeys faild!"); + NapiDrmError::ThrowError(env, "ClearOfflineMediaKeys faild.", DRM_SERVICE_FATAL_ERROR); return nullptr; } } else { DRM_ERR_LOG("MediaKeySystemNapi ClearOfflineMediaKeys call Failed!"); + NapiDrmError::ThrowError(env, "ClearOfflineMediaKeys faild.", DRM_UNKNOWN_ERROR); + return nullptr; } DRM_INFO_LOG("MediaKeySystemNapi::ClearOfflineMediaKeys exit."); @@ -852,19 +899,21 @@ napi_value MediaKeySystemNapi::Destroy(napi_env env, napi_callback_info info) if (status == napi_ok && mediaKeySystemNapi != nullptr && mediaKeySystemNapi->mediaKeySystemImpl_ != nullptr) { int32_t ret = mediaKeySystemNapi->mediaKeySystemImpl_->Release(); if (ret != napi_ok) { + NapiDrmError::ThrowError(env, "Destroy faild.", DRM_SERVICE_FATAL_ERROR); DRM_ERR_LOG("mediaKeySystemImpl_->GetCertificateStatus faild!"); return nullptr; } - mediaKeySystemNapi->~MediaKeySystemNapi(); - mediaKeySystemNapi = nullptr; + MediaKeySystemFactoryImpl::GetInstance()->keySystemNumber--; } else { + NapiDrmError::ThrowError(env, "Destroy faild.", DRM_UNKNOWN_ERROR); DRM_ERR_LOG("mediaKeySystemNapi Destroy Failed!"); + return nullptr; } DRM_INFO_LOG("MediaKeySystemNapi::Release exit."); return result; } -void MediaKeySystemNapi::SaveEventCallbackReferrence(const std::string eventType, sptr callbackPair) +void MediaKeySystemNapi::SaveEventCallbackReferrence(const std::string eventType, std::shared_ptr callbackPair) { DRM_INFO_LOG("MediaKeySystemNapi::SaveEventCallbackReferrence"); std::lock_guard lock(mutex_); @@ -897,12 +946,14 @@ napi_value MediaKeySystemNapi::SetEventCallback(napi_env env, napi_callback_info DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar); NAPI_ASSERT(env, argc == ARGS_TWO, "only requires 2 parameters"); if (thisVar == nullptr || argv[PARAM0] == nullptr || argv[PARAM1] == nullptr) { + NapiDrmError::ThrowError(env, "SetEventCallback faild.", DRM_INVALID_PARAM); DRM_ERR_LOG("Failed to retrieve arguments in SetEventCallback!"); return result; } napi_valuetype valueType = napi_undefined; if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string || napi_typeof(env, argv[PARAM1], &valueType) != napi_ok || valueType != napi_function) { + NapiDrmError::ThrowError(env, "SetEventCallback faild.", DRM_INVALID_PARAM); return result; } @@ -916,10 +967,11 @@ napi_value MediaKeySystemNapi::SetEventCallback(napi_env env, napi_callback_info napi_create_reference(env, argv[PARAM1], 1, &callbackRef); DRM_INFO_LOG("SetEventCallback event is %{public}s", eventType.c_str()); - sptr callbackPair = new CallBackPair(env, callbackRef); + std::shared_ptr callbackPair = std::make_shared(env, callbackRef); mediaKeySystemNapi->SaveEventCallbackReferrence(eventType, callbackPair); DRM_INFO_LOG("mediaKeySystemNapi::SetEventCallback out"); } else { + NapiDrmError::ThrowError(env, "SetEventCallback faild.", DRM_UNKNOWN_ERROR); DRM_ERR_LOG("mediaKeySystemNapi SetEventCallback failed!"); } return result; @@ -937,11 +989,13 @@ napi_value MediaKeySystemNapi::UnsetEventCallback(napi_env env, napi_callback_in NAPI_ASSERT(env, argc == ARGS_ONE, "only requires 1 parameters"); if (thisVar == nullptr || argv[PARAM0] == nullptr) { DRM_ERR_LOG("Failed to retrieve arguments in UnsetEventCallback!"); + NapiDrmError::ThrowError(env, "UnsetEventCallback faild.", DRM_INVALID_PARAM); return result; } napi_valuetype valueType = napi_undefined; if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string) { DRM_ERR_LOG("Failed to retrieve reasonable arguments in UnsetEventCallback!"); + NapiDrmError::ThrowError(env, "UnsetEventCallback faild.", DRM_INVALID_PARAM); return result; } @@ -955,6 +1009,7 @@ napi_value MediaKeySystemNapi::UnsetEventCallback(napi_env env, napi_callback_in mediaKeySystemNapi->ClearEventCallbackReferrence(eventType); DRM_INFO_LOG("MediaKeySystemNapi::UnsetEventCallback out"); } else { + NapiDrmError::ThrowError(env, "UnsetEventCallback faild.", DRM_UNKNOWN_ERROR); DRM_ERR_LOG("MediaKeySystemNapi UnsetEventCallback failed!"); } return result; diff --git a/frameworks/js/drm_napi/napi_async_work.cpp b/frameworks/js/drm_napi/napi_async_work.cpp new file mode 100644 index 00000000..96aa4da6 --- /dev/null +++ b/frameworks/js/drm_napi/napi_async_work.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "napi_async_work.h" + +namespace OHOS { +namespace DrmStandard { +ContextBase::~ContextBase() +{ + DRM_DEBUG_LOG("no memory leak after callback or promise[resolved/rejected]"); + if (env != nullptr) { + if (work != nullptr) { + napi_delete_async_work(env, work); + } + if (callbackRef != nullptr) { + napi_delete_reference(env, callbackRef); + } + napi_delete_reference(env, selfRef); + env = nullptr; + callbackRef = nullptr; + selfRef = nullptr; + } +} + +void ContextBase::GetCbInfo(napi_env envi, napi_callback_info info, NapiCbInfoParser parser, bool sync) +{ + env = envi; + size_t argc = ARGC_MAX; + napi_value argv[ARGC_MAX] = {nullptr}; + status = napi_get_cb_info(env, info, &argc, argv, &self, nullptr); + NAPI_CHECK_STATUS_RETURN_VOID(this, "napi_get_cb_info failed!", DRM_INVALID_PARAM); + NAPI_CHECK_ARGS_RETURN_VOID(this, argc <= ARGC_MAX, "too many arguments!", DRM_INVALID_PARAM); + NAPI_CHECK_ARGS_RETURN_VOID(this, self != nullptr, "no JavaScript this argument!", DRM_INVALID_PARAM); + napi_create_reference(env, self, 1, &selfRef); + status = napi_unwrap(env, self, &native); + NAPI_CHECK_STATUS_RETURN_VOID(this, "self unwrap failed!", DRM_INVALID_PARAM); + + if (!sync && (argc > 0)) { + // get the last arguments :: + size_t index = argc - 1; + napi_valuetype type = napi_undefined; + napi_status tyst = napi_typeof(env, argv[index], &type); + if ((tyst == napi_ok) && (type == napi_function)) { + status = napi_create_reference(env, argv[index], 1, &callbackRef); + NAPI_CHECK_STATUS_RETURN_VOID(this, "ref callback failed!", DRM_INVALID_PARAM); + argc = index; + DRM_DEBUG_LOG("async callback, no promise"); + } else { + DRM_DEBUG_LOG("no callback, async promise"); + } + } + + if (parser) { + parser(argc, argv); + } else { + NAPI_CHECK_ARGS_RETURN_VOID(this, argc == 0, "required no arguments!", DRM_INVALID_PARAM); + } +} + +void ContextBase::SignError(int32_t code) +{ + status = napi_generic_failure; + errCode = code; + errMessage = NapiDrmError::GetMessageByCode(errCode); +} + +napi_value NapiAsyncWork::Enqueue(napi_env env, std::shared_ptr ctxt, const std::string &name, + NapiAsyncExecute execute, NapiAsyncComplete complete) +{ + DRM_DEBUG_LOG("name=%{public}s", name.c_str()); + ctxt->execute = std::move(execute); + ctxt->complete = std::move(complete); + ctxt->taskName = name; + napi_value promise = nullptr; + if (ctxt->callbackRef == nullptr) { + napi_create_promise(ctxt->env, &ctxt->deferred, &promise); + DRM_DEBUG_LOG("create deferred promise"); + } else { + napi_get_undefined(ctxt->env, &promise); + } + + napi_value resource = nullptr; + napi_create_string_utf8(ctxt->env, name.c_str(), NAPI_AUTO_LENGTH, &resource); + napi_create_async_work( + ctxt->env, nullptr, resource, + [](napi_env env, void* data) { + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(data != nullptr, "napi_async_execute_callback nullptr"); + auto ctxt = reinterpret_cast(data); + DRM_DEBUG_LOG("napi_async_execute_callback ctxt->status=%{public}d", ctxt->status); + if (ctxt->execute && ctxt->status == napi_ok) { + ctxt->execute(); + } + }, + [](napi_env env, napi_status status, void* data) { + DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(data != nullptr, "napi_async_complete_callback nullptr"); + auto ctxt = reinterpret_cast(data); + DRM_DEBUG_LOG("napi_async_complete_callback status=%{public}d, ctxt->status=%{public}d", + status, ctxt->status); + if ((status != napi_ok) && (ctxt->status == napi_ok)) { + ctxt->status = status; + } + if ((ctxt->complete) && (status == napi_ok) && (ctxt->status == napi_ok)) { + ctxt->complete(ctxt->output); + } + CommonCallbackRoutine(ctxt); + }, + reinterpret_cast(ctxt.get()), &ctxt->work); + napi_queue_async_work_with_qos(ctxt->env, ctxt->work, napi_qos_user_initiated); + ctxt->hold = ctxt; // save crossing-thread ctxt. + return promise; +} + +void NapiAsyncWork::CommonCallbackRoutine(ContextBase *ctxt) +{ + napi_value result[RESULT_ALL] = {nullptr}; + if (ctxt->status == napi_ok) { + napi_get_undefined(ctxt->env, &result[RESULT_ERROR]); + if (ctxt->output == nullptr) { + napi_get_undefined(ctxt->env, &ctxt->output); + } + result[RESULT_DATA] = ctxt->output; + } else { + napi_value message = nullptr; + napi_value code = nullptr; + napi_create_string_utf8(ctxt->env, ctxt->errMessage.c_str(), NAPI_AUTO_LENGTH, &message); + napi_create_error(ctxt->env, nullptr, message, &result[RESULT_ERROR]); + napi_create_int32(ctxt->env, ctxt->errCode, &code); + napi_set_named_property(ctxt->env, result[RESULT_ERROR], "code", code); + napi_get_undefined(ctxt->env, &result[RESULT_DATA]); + } + if (ctxt->deferred != nullptr) { + if (ctxt->status == napi_ok) { + DRM_DEBUG_LOG("deferred promise resolved"); + napi_resolve_deferred(ctxt->env, ctxt->deferred, result[RESULT_DATA]); + } else { + DRM_DEBUG_LOG("deferred promise rejected"); + napi_reject_deferred(ctxt->env, ctxt->deferred, result[RESULT_ERROR]); + } + } else { + napi_value callback = nullptr; + napi_get_reference_value(ctxt->env, ctxt->callbackRef, &callback); + napi_value callbackResult = nullptr; + DRM_DEBUG_LOG("call callback function"); + napi_call_function(ctxt->env, nullptr, callback, RESULT_ALL, result, &callbackResult); + } + ctxt->hold->execute = nullptr; + ctxt->hold->complete = nullptr; + ctxt->hold.reset(); // release ctxt. +} +} // namespace DrmStandard +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/drm_napi/napi_param_utils.cpp b/frameworks/js/drm_napi/napi_param_utils.cpp new file mode 100644 index 00000000..15406524 --- /dev/null +++ b/frameworks/js/drm_napi/napi_param_utils.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi_param_utils.h" + +namespace OHOS { +namespace DrmStandard { +napi_value NapiParamUtils::GetUndefinedValue(napi_env env) +{ + napi_value result {}; + napi_get_undefined(env, &result); + return result; +} + +napi_status NapiParamUtils::GetValueInt32(const napi_env &env, int32_t &value, napi_value in) +{ + napi_status status = napi_get_value_int32(env, in, &value); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "GetValueInt32 napi_get_value_int32 failed"); + return status; +} + +napi_status NapiParamUtils::SetValueInt32(const napi_env &env, const int32_t &value, napi_value &result) +{ + napi_status status = napi_create_int32(env, value, &result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueInt32 napi_create_int32 failed"); + return status; +} + +napi_status NapiParamUtils::GetValueInt32(const napi_env &env, const std::string &fieldStr, int32_t &value, + napi_value in) +{ + napi_value jsValue = nullptr; + napi_status status = napi_get_named_property(env, in, fieldStr.c_str(), &jsValue); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "GetValueInt32 napi_get_named_property failed"); + status = GetValueInt32(env, value, jsValue); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "GetValueInt32 napi_get_value_int32 failed"); + return status; +} + +napi_status NapiParamUtils::SetValueInt32(const napi_env &env, const std::string &fieldStr, const int32_t value, + napi_value &result) +{ + napi_value jsValue = nullptr; + napi_status status = SetValueInt32(env, value, jsValue); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueInt32 napi_create_int32 failed"); + status = napi_set_named_property(env, result, fieldStr.c_str(), jsValue); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueInt32 napi_create_int32 failed"); + return status; +} + +std::string NapiParamUtils::GetStringArgument(napi_env env, napi_value value) +{ + std::string strValue = ""; + size_t bufLength = 0; + napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &bufLength); + if (status == napi_ok && bufLength > 0 && bufLength < PATH_MAX) { + strValue.reserve(bufLength + 1); + strValue.resize(bufLength); + status = napi_get_value_string_utf8(env, value, strValue.data(), bufLength + 1, &bufLength); + if (status == napi_ok) { + DRM_DEBUG_LOG("argument = %{public}s", strValue.c_str()); + } + } + return strValue; +} + +napi_status NapiParamUtils::SetValueString(const napi_env &env, const std::string &stringValue, napi_value &result) +{ + napi_status status = napi_create_string_utf8(env, stringValue.c_str(), NAPI_AUTO_LENGTH, &result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueString napi_create_string_utf8 failed"); + return status; +} + +napi_status NapiParamUtils::SetValueString(const napi_env &env, const std::string &fieldStr, + const std::string &stringValue, napi_value &result) +{ + napi_value value = nullptr; + napi_status status = SetValueString(env, stringValue.c_str(), value); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueString failed"); + status = napi_set_named_property(env, result, fieldStr.c_str(), value); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueString napi_set_named_property failed"); + return status; +} + +napi_status NapiParamUtils::SetValueUint8Array(const napi_env &env, const std::vector &value, + napi_value &result) +{ + napi_status status = napi_create_array(env, &result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueUint8Array napi_create_array failed"); + for (size_t i = 0; i < value.size(); i++) { + napi_value item; + napi_create_int32(env, value[i], &item); + napi_set_element(env, result, i, item); + } + return status; +} + +napi_status NapiParamUtils::SetValueUint8Array(const napi_env &env, const std::string &fieldStr, + const std::vector &value, napi_value &result) +{ + napi_value jsValue = nullptr; + napi_status status = SetValueUint8Array(env, value, jsValue); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueUint8Array failed"); + status = napi_set_named_property(env, result, fieldStr.c_str(), jsValue); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "napi_set_named_property failed"); + return status; +} + +napi_status NapiParamUtils::GetValueUint8Array(const napi_env &env, std::vector &value, napi_value in) +{ + void *reponseData = nullptr; + size_t reponseDataLen; + size_t offset; + napi_value arraybuffer = nullptr; + napi_typedarray_type type; + napi_status status = napi_get_typedarray_info(env, in, &type, &reponseDataLen, &reponseData, &arraybuffer, &offset); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "napi_get_typedarray_info failed"); + uint8_t *reponseDataPtr = reinterpret_cast(reponseData); + std::vector initDataStr(reponseDataPtr, reponseDataPtr + reponseDataLen); + value.assign(initDataStr.begin(), initDataStr.end()); + return status; +} + +napi_status NapiParamUtils::SetValueBoolean(const napi_env &env, const bool boolValue, napi_value &result) +{ + napi_status status = napi_get_boolean(env, boolValue, &result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueBoolean napi_get_boolean failed"); + return status; +} + +napi_status NapiParamUtils::SetValueMap(const napi_env &env, + std::map, MediaKeySessionKeyStatus> statusTable, napi_value &statusTableMap) +{ + uint32_t index = 0; + napi_status status; + napi_create_array_with_length(env, statusTable.size(), &statusTableMap); + for (auto itemTmp : statusTable) { + napi_value jsObject; + napi_value jsKeyId; + napi_value jsKeyStatus; + napi_create_object(env, &jsObject); + status = napi_create_array_with_length(env, itemTmp.first.size(), &jsKeyId); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "failed to call napi_create_array_with_length"); + for (uint32_t i = 0; i < itemTmp.first.size(); i++) { + napi_value number = nullptr; + (void)napi_create_uint32(env, itemTmp.first[i], &number); + (void)napi_set_element(env, jsKeyId, i, number); + } + status = napi_set_named_property(env, jsObject, "keyId", jsKeyId); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "failed to call napi_set_named_property"); + std::string value; + switch (itemTmp.second) { + case MEDIA_KEY_SESSION_KEY_STATUS_USABLE: + value = "USABLE"; + break; + case MEDIA_KEY_SESSION_KEY_STATUS_EXPIRED: + value = "EXPIRED"; + break; + case MEDIA_KEY_SESSION_KEY_STATUS_OUTPUT_NOT_ALLOWED: + value = "OUTPUT_NOT_ALLOWED"; + break; + case MEDIA_KEY_SESSION_KEY_STATUS_PENDING: + value = "PENDING"; + break; + case MEDIA_KEY_SESSION_KEY_STATUS_INTERNAL_ERROR: + value = "INTERNAL_ERROR"; + break; + case MEDIA_KEY_SESSION_KEY_STATUS_USABLE_IN_FUTURE: + value = "USABLE_IN_FUTURE"; + break; + default: + value = "Fault Status"; + break; + } + status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &jsKeyStatus); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "failed to call napi_create_string_utf8"); + status = napi_set_named_property(env, jsObject, "value", jsKeyStatus); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "failed to call napi_set_named_property"); + status = napi_set_element(env, statusTableMap, index, jsObject); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "failed to call napi_set_element"); + index++; + } + return status; +} + +napi_status NapiParamUtils::GetValueOptionsData(const napi_env &env, std::map &valueMap, + napi_value in) +{ + uint32_t optionalDataCount = 0; + napi_status status = napi_get_array_length(env, in, &optionalDataCount); + if (optionalDataCount > 0) { + for (size_t i = 0; i < optionalDataCount; i++) { + napi_value tmpData; + napi_value tmpName; + napi_value tmpValue; + size_t nameLength = 0; + size_t valueLength = 0; + status = napi_get_element(env, in, i, &tmpData); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "Could not able to read optionalData element!"); + status = napi_get_named_property(env, tmpData, "name", &tmpName); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "Could not able to read optionalData property!"); + status = napi_get_named_property(env, tmpData, "value", &tmpValue); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "Could not able to read optionalData property!"); + status = napi_get_value_string_utf8(env, tmpName, nullptr, 0, &nameLength); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, + "Could not able to transfer optionalData buffer info!"); + status = napi_get_value_string_utf8(env, tmpValue, nullptr, 0, &valueLength); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, + "Could not able to transfer optionalData buffer info!"); + std::string name(nameLength, 0); + status = napi_get_value_string_utf8(env, tmpName, &name[0], nameLength + 1, &nameLength); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, + "Could not able to transfer optionalData buffer info!"); + std::string value(valueLength, 0); + status = napi_get_value_string_utf8(env, tmpValue, &value[0], valueLength + 1, &valueLength); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, + "Could not able to transfer optionalData buffer info!"); + valueMap.insert(std::make_pair(name, value)); + } + } + return status; +} + +napi_status NapiParamUtils::SetProvisionRequest(const napi_env &env, const NapiProvisionRequest &provisionRequest, + napi_value &result) +{ + napi_status status = napi_create_object(env, &result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetProvisionRequest napi_create_object failed"); + status = SetValueString(env, "defaultURL", provisionRequest.defaultURL, result); + status = SetValueUint8Array(env, "data", provisionRequest.data, result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetProvisionRequest SetValueUint8Array failed"); + return status; +} + +napi_status NapiParamUtils::SetMediaKeyRequest(const napi_env &env, + const IMediaKeySessionService::MediaKeyRequest &mediaKeyRequest, napi_value &result) +{ + napi_status status = napi_create_object(env, &result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetMediaKeyRequest napi_create_object failed"); + status = SetValueInt32(env, "mediaKeyRequestType", mediaKeyRequest.requestType, result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetMediaKeyRequest SetValueInt32 failed"); + status = SetValueUint8Array(env, "data", mediaKeyRequest.mData, result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetMediaKeyRequest SetValueUint8Array failed"); + status = SetValueString(env, "defaultURL", mediaKeyRequest.mDefaultURL, result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetMediaKeyRequest SetValueString failed"); + return status; +} + +napi_status NapiParamUtils::SetDrmEventInfo(const napi_env &env, DrmEventParame &eventParame, napi_value &result) +{ + napi_status status = napi_create_object(env, &result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetDrmEventInfo napi_create_object failed"); + status = SetValueUint8Array(env, "info", eventParame.data, result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetDrmEventInfo SetValueUint8Array failed"); + status = SetValueString(env, "extraInfo", std::to_string(eventParame.extra), result); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetDrmEventInfo SetValueString failed"); + return status; +} + +napi_status NapiParamUtils::SetDrmKeysChangeEventInfo(const napi_env &env, DrmKeysChangeEventParame &eventParame, + napi_value &statusTable, napi_value &hasNewGoodLicense) +{ + napi_status status = SetValueMap(env, eventParame.statusTable, statusTable); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetDrmKeysChangeEventInfo SetValueMap failed"); + status = SetValueBoolean(env, eventParame.hasNewGoodLicense, hasNewGoodLicense); + DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetDrmKeysChangeEventInfo SetValueBoolean failed"); + return napi_ok; +} +} // namespace DrmStandard +} // namespace OHOS diff --git a/frameworks/native/BUILD.gn b/frameworks/native/BUILD.gn index 572ba066..2f114907 100644 --- a/frameworks/native/BUILD.gn +++ b/frameworks/native/BUILD.gn @@ -79,6 +79,8 @@ ohos_shared_library("drm_framework") { deps = [] external_deps = [ + "ability_runtime:abilitykit_native", + "ability_runtime:napi_base_context", "c_utils:utils", "hilog:libhilog", "hisysevent:libhisysevent", diff --git a/frameworks/native/drm/key_session_impl.cpp b/frameworks/native/drm/key_session_impl.cpp index 17409805..17c9ff65 100644 --- a/frameworks/native/drm/key_session_impl.cpp +++ b/frameworks/native/drm/key_session_impl.cpp @@ -97,7 +97,6 @@ int32_t MediaKeySessionImpl::GenerateOfflineReleaseRequest(std::vector DRM_INFO_LOG("MediaKeySessionImpl::GenerateOfflineReleaseRequest enter."); std::lock_guard lock(mutex_); int32_t retCode = DRM_OK; - if (keySessionServiceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySessionImpl::GenerateOfflineReleaseRequest keySessionServiceProxy_ is null"); return DRM_SERVICE_ERROR; diff --git a/frameworks/native/drm/media_key_system_factory_impl.cpp b/frameworks/native/drm/media_key_system_factory_impl.cpp index 9c345b04..9dedf88c 100644 --- a/frameworks/native/drm/media_key_system_factory_impl.cpp +++ b/frameworks/native/drm/media_key_system_factory_impl.cpp @@ -15,6 +15,8 @@ #include "media_key_system_factory_impl.h" #include "i_mediakeysystem_service.h" +#include "drm_error_code.h" +#include "napi_param_utils.h" namespace OHOS { namespace DrmStandard { @@ -95,15 +97,15 @@ bool MediaKeySystemFactoryImpl::IsMediaKeySystemSupported(std::string &uuid) { DRM_INFO_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported enter."); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; bool isSurpported = false; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported serviceProxy_ is null"); return isSurpported; } - retCode = serviceProxy_->IsMediaKeySystemSupported(uuid, &isSurpported); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported failed, retCode: %{public}d", retCode); + ret = serviceProxy_->IsMediaKeySystemSupported(uuid, &isSurpported); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported failed, ret: %{public}d", ret); } DRM_INFO_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported exit."); @@ -114,16 +116,16 @@ bool MediaKeySystemFactoryImpl::IsMediaKeySystemSupported(std::string &uuid, std { DRM_INFO_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported enter."); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; bool isSurpported = false; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported serviceProxy_ is null"); return isSurpported; } - retCode = serviceProxy_->IsMediaKeySystemSupported(uuid, mimeType, &isSurpported); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported failed, retCode: %{public}d", retCode); + ret = serviceProxy_->IsMediaKeySystemSupported(uuid, mimeType, &isSurpported); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported failed, ret: %{public}d", ret); } DRM_INFO_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported exit."); @@ -135,16 +137,16 @@ bool MediaKeySystemFactoryImpl::IsMediaKeySystemSupported(std::string &uuid, std { DRM_INFO_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported enter."); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; bool isSurpported = false; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported serviceProxy_ is null"); return isSurpported; } - retCode = serviceProxy_->IsMediaKeySystemSupported(uuid, mimeType, securityLevel, &isSurpported); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported failed, retCode: %{public}d", retCode); + ret = serviceProxy_->IsMediaKeySystemSupported(uuid, mimeType, securityLevel, &isSurpported); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported failed, ret: %{public}d", ret); } DRM_INFO_LOG("MediaKeySystemFactoryImpl::IsMediaKeySystemSupported exit."); @@ -156,31 +158,37 @@ int32_t MediaKeySystemFactoryImpl::CreateMediaKeySystem(std::string &uuid, sptr< DRM_INFO_LOG("MediaKeySystemFactoryImpl:: CreateMediaKeySystem enter."); sptr mediaKeySystemProxy = nullptr; sptr localMediaKeySystemImpl = nullptr; - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (mediaKeySystemImpl == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl:: mediaKeySystemImpl is nullptr"); - return DRM_INVALID_ARG; + return DRM_INVALID_PARAM; } if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemFactoryImpl:: serviceProxy_ == nullptr"); - return DRM_SERVICE_ERROR; + return DRM_SERVICE_FATAL_ERROR; } - retCode = serviceProxy_->CreateMediaKeySystem(uuid, mediaKeySystemProxy); - if (retCode == DRM_OK) { + ret = serviceProxy_->CreateMediaKeySystem(uuid, mediaKeySystemProxy); + if (ret == DRM_OK) { if (mediaKeySystemProxy != nullptr) { localMediaKeySystemImpl = new (std::nothrow) MediaKeySystemImpl(mediaKeySystemProxy); if (localMediaKeySystemImpl == nullptr) { DRM_ERR_LOG("Failed to new MediaKeySystemImpl"); - return DRM_ALLOC_ERROR; + return DRM_SERVICE_FATAL_ERROR; + } + keySystemNumber++; + if (keySystemNumber > KEY_SYSTEM_MAX_NUMBER) { + keySystemNumber--; + DRM_ERR_LOG("The number of MediaKeySystem is greater than 64"); + return DRM_MAX_SYSTEM_NUM_REACHED; } } else { DRM_ERR_LOG("mediaKeySystemProxy is nullptr"); return DRM_UNKNOWN_ERROR; } } else { - DRM_ERR_LOG("Failed to get session object from mediakeysystem service!, %{public}d", retCode); - return DRM_SERVICE_ERROR; + DRM_ERR_LOG("Failed to get session object from mediakeysystem service!, %{public}d", ret); + return DRM_SERVICE_FATAL_ERROR; } *mediaKeySystemImpl = localMediaKeySystemImpl; DRM_INFO_LOG("MediaKeySystemFactoryImpl:: CreateMediaKeySystem exit."); diff --git a/frameworks/native/drm/media_key_system_impl.cpp b/frameworks/native/drm/media_key_system_impl.cpp index 52de4350..2615c9a5 100644 --- a/frameworks/native/drm/media_key_system_impl.cpp +++ b/frameworks/native/drm/media_key_system_impl.cpp @@ -15,6 +15,8 @@ #include "media_key_system_impl.h" #include "i_mediakeysystem_service.h" +#include "drm_error_code.h" +#include "napi_param_utils.h" namespace OHOS { namespace DrmStandard { @@ -52,15 +54,15 @@ int32_t MediaKeySystemImpl::GenerateKeySystemRequest(std::vector &reque { DRM_INFO_LOG("MediaKeySystemImpl::GenerateKeySystemRequest enter."); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::GenerateKeySystemRequest serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->GenerateKeySystemRequest(request, defaultUrl); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::GenerateKeySystemRequest failed, retCode: %{public}d", retCode); + ret = serviceProxy_->GenerateKeySystemRequest(request, defaultUrl); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::GenerateKeySystemRequest failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } DRM_INFO_LOG("MediaKeySystemImpl::GenerateKeySystemRequest exit."); @@ -71,15 +73,15 @@ int32_t MediaKeySystemImpl::ProcessKeySystemResponse(const std::vector { DRM_INFO_LOG("MediaKeySystemImpl::ProcessKeySystemResponse enter."); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::ProcessKeySystemResponse serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->ProcessKeySystemResponse(response); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::ProcessKeySystemResponse failed, retCode: %{public}d", retCode); + ret = serviceProxy_->ProcessKeySystemResponse(response); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::ProcessKeySystemResponse failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } DRM_INFO_LOG("MediaKeySystemImpl::ProcessKeySystemResponse exit."); @@ -91,15 +93,15 @@ int32_t MediaKeySystemImpl::SetConfigurationString(std::string &configName, std: DRM_INFO_LOG("MediaKeySystemImpl::SetConfiguration enter, configName:%{public}s, value:%{public}s.", configName.c_str(), value.c_str()); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::SetConfiguration serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->SetConfigurationString(configName, value); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::SetConfiguration failed, retCode: %{public}d", retCode); + ret = serviceProxy_->SetConfigurationString(configName, value); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::SetConfiguration failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } DRM_INFO_LOG("MediaKeySystemImpl::SetConfiguration exit."); @@ -110,15 +112,15 @@ int32_t MediaKeySystemImpl::GetConfigurationString(std::string &configName, std: { DRM_INFO_LOG("MediaKeySystemImpl::GetConfiguration enter, configName:%{public}s.", configName.c_str()); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::GetConfiguration serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->GetConfigurationString(configName, value); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::GetConfiguration failed, retCode: %{public}d", retCode); + ret = serviceProxy_->GetConfigurationString(configName, value); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::GetConfiguration failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } @@ -130,15 +132,15 @@ int32_t MediaKeySystemImpl::SetConfigurationByteArray(std::string &configName, s { DRM_INFO_LOG("MediaKeySystemImpl::SetConfiguration enter, configName:%{public}s.", configName.c_str()); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::SetConfiguration serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->SetConfigurationByteArray(configName, value); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::SetConfiguration failed, retCode: %{public}d", retCode); + ret = serviceProxy_->SetConfigurationByteArray(configName, value); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::SetConfiguration failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } DRM_INFO_LOG("MediaKeySystemImpl::SetConfiguration exit."); @@ -149,15 +151,15 @@ int32_t MediaKeySystemImpl::GetConfigurationByteArray(std::string &configName, s { DRM_INFO_LOG("MediaKeySystemImpl::GetConfiguration enter, configName:%{public}s.", configName.c_str()); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::GetConfiguration serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->GetConfigurationByteArray(configName, value); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::GetConfiguration failed, retCode: %{public}d", retCode); + ret = serviceProxy_->GetConfigurationByteArray(configName, value); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::GetConfiguration failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } @@ -170,30 +172,47 @@ int32_t MediaKeySystemImpl::CreateMediaKeySession(IMediaKeySessionService::Conte DRM_INFO_LOG("MediaKeySystemImpl::CreateMediaKeySession enter."); sptr keySessionProxy = nullptr; sptr localMediaKeySessionImpl = nullptr; - int32_t retCode = DRM_OK; - + int32_t ret = DRM_OK; + /* To determine if any members in the keySession list have been destroyed, + * the keySessionNumber needs to be reduced by one + */ + for (size_t i = 0; i < keySessionVec.size(); i++) { + /* In the case of initial and complete destruction, + * all members of the keySession list are null pointers + */ + if (keySessionNumber > 0 && keySessionVec[i] == nullptr) { + keySessionNumber--; + keySessionVec.erase(keySessionVec.begin() + i); + } + } if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl:: serviceProxy_ == nullptr"); - return DRM_SERVICE_ERROR; + return DRM_SERVICE_FATAL_ERROR; } - retCode = serviceProxy_->CreateMediaKeySession(securityLevel, keySessionProxy); - if (retCode == DRM_OK) { + ret = serviceProxy_->CreateMediaKeySession(securityLevel, keySessionProxy); + if (ret == DRM_OK) { if (keySessionProxy != nullptr) { localMediaKeySessionImpl = new (std::nothrow) MediaKeySessionImpl(keySessionProxy); if (localMediaKeySessionImpl == nullptr) { DRM_ERR_LOG("Failed to new MediaKeySessionImpl"); - return DRM_ALLOC_ERROR; + return DRM_SERVICE_FATAL_ERROR; } + if (keySessionNumber > KEY_SESSION_MAX_NUMBER) { + DRM_ERR_LOG("The number of MediaKeySession is greater than 64"); + return DRM_MAX_SESSION_NUM_REACHED; + } + keySessionNumber++; } else { DRM_ERR_LOG("Failed to CreateMediaKeySessionImpl with session is null"); return DRM_UNKNOWN_ERROR; } } else { - DRM_ERR_LOG("Failed to get session object from mediakeysystem service!, %{public}d", retCode); - return DRM_SERVICE_ERROR; + DRM_ERR_LOG("Failed to get session object from mediakeysystem service!, %{public}d", ret); + return DRM_SERVICE_FATAL_ERROR; } *keySessionImpl = localMediaKeySessionImpl; + keySessionVec.push_back(localMediaKeySessionImpl); DRM_INFO_LOG("MediaKeySystemImpl::CreateMediaKeySession exit."); return DRM_OK; } @@ -202,15 +221,15 @@ int32_t MediaKeySystemImpl::GetStatistics(std::vector lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::GetStatistics serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->GetStatistics(metrics); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::GetStatistics failed, retCode: %{public}d", retCode); + ret = serviceProxy_->GetStatistics(metrics); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::GetStatistics failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } DRM_INFO_LOG("MediaKeySystemImpl::GetStatistics exit."); @@ -221,17 +240,17 @@ int32_t MediaKeySystemImpl::GetMaxContentProtectionLevel(IMediaKeySessionService { DRM_INFO_LOG("MediaKeySystemImpl::GetMaxContentProtectionLevel enter."); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::GetMaxContentProtectionLevel serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = + ret = serviceProxy_->GetMaxContentProtectionLevel((IMediaKeySessionService::ContentProtectionLevel *)securityLevel); DRM_ERR_LOG("MediaKeySystemImpl::GetMaxContentProtectionLevel 277"); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::GetMaxContentProtectionLevel failed, retCode: %{public}d", retCode); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::GetMaxContentProtectionLevel failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } DRM_INFO_LOG("MediaKeySystemImpl::GetMaxContentProtectionLevel exit."); @@ -242,15 +261,15 @@ int32_t MediaKeySystemImpl::GetOfflineMediaKeyIds(std::vector lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::GetOfflineMediaKeyIds serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->GetOfflineMediaKeyIds(licenseIds); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::GetOfflineMediaKeyIds failed, retCode: %{public}d", retCode); + ret = serviceProxy_->GetOfflineMediaKeyIds(licenseIds); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::GetOfflineMediaKeyIds failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } DRM_INFO_LOG("MediaKeySystemImpl::GetOfflineMediaKeyIds exit"); @@ -262,15 +281,15 @@ int32_t MediaKeySystemImpl::GetOfflineMediaKeyStatus(std::vector &licen { DRM_INFO_LOG("MediaKeySystemImpl::GetOfflineMediaKeyStatus enter."); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::GetOfflineMediaKeyStatus serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->GetOfflineMediaKeyStatus(licenseId, status); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::GetOfflineMediaKeyStatus failed, retCode: %{public}d", retCode); + ret = serviceProxy_->GetOfflineMediaKeyStatus(licenseId, status); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::GetOfflineMediaKeyStatus failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } DRM_INFO_LOG("MediaKeySystemImpl::GetOfflineMediaKeyStatus exit."); @@ -281,14 +300,14 @@ int32_t MediaKeySystemImpl::ClearOfflineMediaKeys(std::vector &licenseI { DRM_INFO_LOG("MediaKeySystemImpl::ClearOfflineMediaKeys enter."); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::ClearOfflineMediaKeys serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->ClearOfflineMediaKeys(licenseId); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::ClearOfflineMediaKeys failed, retCode: %{public}d", retCode); + ret = serviceProxy_->ClearOfflineMediaKeys(licenseId); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::ClearOfflineMediaKeys failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } DRM_INFO_LOG("MediaKeySystemImpl::ClearOfflineMediaKeys exit"); @@ -299,16 +318,16 @@ int32_t MediaKeySystemImpl::GetCertificateStatus(IMediaKeySystemService::Certifi { DRM_INFO_LOG("MediaKeySystemImpl::GetCertificateStatus enter."); std::lock_guard lock(mutex_); - int32_t retCode = DRM_OK; + int32_t ret = DRM_OK; if (serviceProxy_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl::GetCertificateStatus serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->GetCertificateStatus((IMediaKeySystemService::CertificateStatus *)certStatus); + ret = serviceProxy_->GetCertificateStatus((IMediaKeySystemService::CertificateStatus *)certStatus); DRM_ERR_LOG("MediaKeySystemImpl::GetCertificateStatus 277"); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::GetCertificateStatus failed, retCode: %{public}d", retCode); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::GetCertificateStatus failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } DRM_INFO_LOG("MediaKeySystemImpl::GetCertificateStatus exit."); @@ -321,11 +340,11 @@ int32_t MediaKeySystemImpl::SetCallback(const sptr & DRM_CHECK_AND_RETURN_RET_LOG(callback != nullptr, DRM_INVALID_ARG, "callback is nullptr"); mediaKeySystemApplicationCallback_ = callback; - int32_t retCode = DRM_ERROR; + int32_t ret = DRM_ERROR; serviceCallback_ = new (std::nothrow) MediaKeySystemCallback(this); if (serviceCallback_ == nullptr) { DRM_ERR_LOG("MediaKeySystemImpl:: MediaKeySystemCallback alloc failed"); - return retCode; + return ret; } std::lock_guard lock(mutex_); @@ -333,13 +352,13 @@ int32_t MediaKeySystemImpl::SetCallback(const sptr & DRM_ERR_LOG("MediaKeySystemImpl::SetCallback serviceProxy_ is null"); return DRM_SERVICE_ERROR; } - retCode = serviceProxy_->SetCallback(serviceCallback_); - if (retCode != DRM_OK) { - DRM_ERR_LOG("MediaKeySystemImpl::SetCallback failed, retCode: %{public}d", retCode); + ret = serviceProxy_->SetCallback(serviceCallback_); + if (ret != DRM_OK) { + DRM_ERR_LOG("MediaKeySystemImpl::SetCallback failed, ret: %{public}d", ret); return DRM_SERVICE_ERROR; } DRM_INFO_LOG("MediaKeySystemImpl::SetCallback exit."); - return retCode; + return ret; } sptr MediaKeySystemImpl::GetApplicationCallback() diff --git a/frameworks/native/test/unittest/BUILD.gn b/frameworks/native/test/unittest/BUILD.gn index 23a17833..7d81fc4a 100644 --- a/frameworks/native/test/unittest/BUILD.gn +++ b/frameworks/native/test/unittest/BUILD.gn @@ -55,6 +55,7 @@ ohos_unittest("drm_framework_capi_unittest_v1_0") { deps = [ "../../../../frameworks/native:drm_framework", "../../../../interfaces/kits/c/drm_capi:native_drm", + "../../../../interfaces/kits/js/drm_napi:drm_napi", "../../../../services/drm_service:drm_service", "//third_party/googletest:gmock_main", ] diff --git a/frameworks/native/test/unittest/src/drm_framework_unittest.cpp b/frameworks/native/test/unittest/src/drm_framework_unittest.cpp index 8fd41444..4248f2c7 100644 --- a/frameworks/native/test/unittest/src/drm_framework_unittest.cpp +++ b/frameworks/native/test/unittest/src/drm_framework_unittest.cpp @@ -18,7 +18,6 @@ #include #include #include "drm_log.h" -#include "drm_error_code.h" #include "native_drm_base.h" #include "native_drm_object.h" #include "key_session_impl.h" @@ -29,7 +28,6 @@ #include "native_drm_common.h" #include "native_drm_err.h" #include "gmock/gmock.h" -#include "drm_error_code.h" #include "native_drm_base.h" #include "native_drm_object.h" #include "key_session_impl.h" @@ -49,7 +47,6 @@ #include "drm_types.h" #include "drm_framework_unittest.h" #include "drm_log.h" -#include "drm_error_code.h" #define DRM_SAMPLE_CHECK_AND_RETURN_RET_LOG(cond, ret, fmt, ...) \ do { \ diff --git a/interfaces/inner_api/native/drm/key_session_impl.h b/interfaces/inner_api/native/drm/key_session_impl.h index 2ff1be8b..fa3a2496 100644 --- a/interfaces/inner_api/native/drm/key_session_impl.h +++ b/interfaces/inner_api/native/drm/key_session_impl.h @@ -39,7 +39,7 @@ class MediaKeySessionImplCallback : public RefBase { public: MediaKeySessionImplCallback() = default; virtual ~MediaKeySessionImplCallback() = default; - virtual void SendEvent(const std::string event, int32_t extra, const std::vector data) = 0; + virtual void SendEvent(const std::string &event, int32_t extra, const std::vector &data) = 0; virtual void SendEventKeyChanged(std::map, MediaKeySessionKeyStatus> statusTable, bool hasNewGoodLicense) = 0; }; diff --git a/interfaces/inner_api/native/drm/media_key_system_factory_impl.h b/interfaces/inner_api/native/drm/media_key_system_factory_impl.h index 1d79fd56..cf03b7a7 100644 --- a/interfaces/inner_api/native/drm/media_key_system_factory_impl.h +++ b/interfaces/inner_api/native/drm/media_key_system_factory_impl.h @@ -24,7 +24,6 @@ #include "i_mediakeysystemfactory_service.h" #include "drm_death_recipient.h" #include "drm_log.h" -#include "drm_error_code.h" namespace OHOS { namespace DrmStandard { @@ -39,6 +38,7 @@ public: bool IsMediaKeySystemSupported(std::string &uuid, std::string &mimeType, IMediaKeySessionService::ContentProtectionLevel securityLevel); int32_t CreateMediaKeySystem(std::string &uuid, sptr *mediaKeySystemImpl); + int32_t keySystemNumber = 0; private: void MediaKeySystemServerDied(pid_t pid); diff --git a/interfaces/inner_api/native/drm/media_key_system_impl.h b/interfaces/inner_api/native/drm/media_key_system_impl.h index 82838795..455603de 100644 --- a/interfaces/inner_api/native/drm/media_key_system_impl.h +++ b/interfaces/inner_api/native/drm/media_key_system_impl.h @@ -21,7 +21,6 @@ #include "nocopyable.h" #include "system_ability_definition.h" #include "drm_log.h" -#include "drm_error_code.h" #include "drm_death_recipient.h" #include "key_session_impl.h" #include "i_mediakeysystem_service.h" @@ -36,7 +35,7 @@ class MediaKeySystemImplCallback : public RefBase { public: MediaKeySystemImplCallback() = default; virtual ~MediaKeySystemImplCallback() = default; - virtual void SendEvent(const std::string event, int32_t extra, const std::vector data) = 0; + virtual void SendEvent(const std::string &event, int32_t extra, const std::vector &data) = 0; }; class MediaKeySystemImpl : public RefBase { @@ -71,6 +70,8 @@ private: sptr serviceProxy_; sptr mediaKeySystemApplicationCallback_; sptr serviceCallback_; + std::vector> keySessionVec; + uint32_t keySessionNumber = 0; }; class MediaKeySystemCallback : public MeidaKeySystemServiceCallbackStub { diff --git a/interfaces/kits/c/drm_capi/common/native_drm_object.h b/interfaces/kits/c/drm_capi/common/native_drm_object.h index d58ecfc6..f4af0845 100644 --- a/interfaces/kits/c/drm_capi/common/native_drm_object.h +++ b/interfaces/kits/c/drm_capi/common/native_drm_object.h @@ -83,7 +83,7 @@ public: callback_ = nullptr; } - void SendEvent(const std::string event, int32_t extra, const std::vector data) override + void SendEvent(const std::string &event, int32_t extra, const std::vector &data) override { DRM_INFO_LOG("MediaKeySystemCallbackCapi SendEvent."); std::lock_guard lock(mutex_); @@ -150,7 +150,7 @@ public: callback_ = {}; } - void SendEvent(const std::string event, int32_t extra, const std::vector data) override + void SendEvent(const std::string &event, int32_t extra, const std::vector &data) override { DRM_INFO_LOG("MediaKeySessionCallbackCapi SendEvent."); std::lock_guard lock(mutex_); diff --git a/interfaces/kits/js/drm_napi/BUILD.gn b/interfaces/kits/js/drm_napi/BUILD.gn index 78a44fb4..8291a680 100644 --- a/interfaces/kits/js/drm_napi/BUILD.gn +++ b/interfaces/kits/js/drm_napi/BUILD.gn @@ -30,7 +30,6 @@ ohos_copy("drm_declaration") { ohos_shared_library("drm_napi") { include_dirs = [ - "./../../../../frameworks/js/common", "./../../../../frameworks/js/drm_napi", "./../../../../frameworks/native/drm", "./../../../../frameworks/native/common", @@ -45,15 +44,20 @@ ohos_shared_library("drm_napi") { ] sources = [ "./../../../../frameworks/js/drm_napi/drm_enum_napi.cpp", + "./../../../../frameworks/js/drm_napi/drm_error_code.cpp", "./../../../../frameworks/js/drm_napi/drm_napi.cpp", "./../../../../frameworks/js/drm_napi/key_session_callback_napi.cpp", "./../../../../frameworks/js/drm_napi/key_session_napi.cpp", "./../../../../frameworks/js/drm_napi/media_key_system_callback_napi.cpp", "./../../../../frameworks/js/drm_napi/media_key_system_napi.cpp", + "./../../../../frameworks/js/drm_napi/napi_async_work.cpp", + "./../../../../frameworks/js/drm_napi/napi_param_utils.cpp", "./../../../../frameworks/js/drm_napi/native_module_ohos_drm.cpp", ] deps = [ "./../../../../frameworks/native:drm_framework" ] external_deps = [ + "ability_runtime:abilitykit_native", + "ability_runtime:napi_base_context", "access_token:libtokenid_sdk", "c_utils:utils", "hilog:libhilog", diff --git a/interfaces/kits/js/drm_napi/include/key_session_callback_napi.h b/interfaces/kits/js/drm_napi/include/key_session_callback_napi.h index 00c08c35..d4820b2d 100644 --- a/interfaces/kits/js/drm_napi/include/key_session_callback_napi.h +++ b/interfaces/kits/js/drm_napi/include/key_session_callback_napi.h @@ -21,22 +21,37 @@ #include "napi/native_api.h" #include "napi/native_node_api.h" #include "common_napi.h" +#include "napi_param_utils.h" +#include "napi_async_work.h" namespace OHOS { namespace DrmStandard { class MediaKeySessionCallbackNapi : public MediaKeySessionImplCallback { public: - explicit MediaKeySessionCallbackNapi(); + explicit MediaKeySessionCallbackNapi(napi_env env); virtual ~MediaKeySessionCallbackNapi(); - void SetCallbackReference(const std::string eventType, sptr callbackPair); + void SetCallbackReference(const std::string eventType, std::shared_ptr callbackPair); void ClearCallbackReference(const std::string eventType); - void SendEvent(const std::string event, int32_t extra, const std::vector data) override; + void SendEvent(const std::string &event, int32_t extra, const std::vector &data) override; void SendEventKeyChanged(std::map, MediaKeySessionKeyStatus> statusTable, bool hasNewGoodLicense) override; private: + struct MediaKeySessionJsCallback { + std::shared_ptr callback = nullptr; + std::string callbackName = "unknown"; + DrmEventParame eventParame; + DrmKeysChangeEventParame keysChangeParame; + }; + + static void WorkCallbackStateChangeDone(uv_work_t *work, int status); + static void WorkCallbackInterruptDone(uv_work_t *work, int status); + void OnJsCallbackInterrupt(std::unique_ptr &jsCb); + void OnJsCallbackStateChange(std::unique_ptr &jsCb); + + napi_env env_ = nullptr; std::mutex mutex_; - std::map> callbackMap_; + std::map> callbackMap_; }; } // namespace DrmStandard } // namespace OHOS diff --git a/interfaces/kits/js/drm_napi/include/key_session_napi.h b/interfaces/kits/js/drm_napi/include/key_session_napi.h index d1bfc1ac..f1b94f77 100644 --- a/interfaces/kits/js/drm_napi/include/key_session_napi.h +++ b/interfaces/kits/js/drm_napi/include/key_session_napi.h @@ -22,10 +22,27 @@ #include "drm_error_code.h" #include "key_session_callback_napi.h" #include "key_session_impl.h" +#include "napi_param_utils.h" +#include "drm_error_code.h" +#include "napi_async_work.h" namespace OHOS { namespace DrmStandard { static const char KEY_SESSION_NAPI_CLASS_NAME[] = "MediaKeySession"; + +struct MediaKeySessionAsyncContext : public ContextBase { + int32_t intValue; + std::vector response; + std::vector licenseId; + std::vector releaseRequest; + std::vector releaseLicenseId; + std::vector restoreLicenseId; + std::vector releaseResponse; + std::vector releaseResponseLicenseId; + IMediaKeySessionService::MediaKeyRequestInfo mediaKeyRequestInfo; + IMediaKeySessionService::MediaKeyRequest mediaKeyRequest; +}; + class MediaKeySessionNapi { public: MediaKeySessionNapi(); @@ -48,9 +65,12 @@ public: static napi_value UnsetEventCallback(napi_env env, napi_callback_info info); static bool SetMediaKeySessionNativeProperty(napi_env env, napi_value obj, const std::string &name, sptr keySessionImpl); - void SetEventCallbackReference(const std::string eventType, sptr callbackPair); + void SetEventCallbackReference(const std::string eventType, std::shared_ptr callbackPair); void ClearEventCallbackReference(const std::string eventType); static napi_value Destroy(napi_env env, napi_callback_info info); + static bool CheckMediaKeySessionStatus(MediaKeySessionNapi *napi, + std::shared_ptr context); + static bool CheckContextStatus(std::shared_ptr context); private: static napi_value MediaKeySessionNapiConstructor(napi_env env, napi_callback_info info); diff --git a/interfaces/kits/js/drm_napi/include/media_key_system_callback_napi.h b/interfaces/kits/js/drm_napi/include/media_key_system_callback_napi.h index be94087a..57f35ba9 100644 --- a/interfaces/kits/js/drm_napi/include/media_key_system_callback_napi.h +++ b/interfaces/kits/js/drm_napi/include/media_key_system_callback_napi.h @@ -19,20 +19,33 @@ #include "napi/native_node_api.h" #include "common_napi.h" #include "media_key_system_impl.h" +#include "napi_param_utils.h" +#include "napi_async_work.h" namespace OHOS { namespace DrmStandard { class MediaKeySystemCallbackNapi : public MediaKeySystemImplCallback { public: - explicit MediaKeySystemCallbackNapi(); + explicit MediaKeySystemCallbackNapi(napi_env env); virtual ~MediaKeySystemCallbackNapi(); - void SetCallbackReference(const std::string eventType, sptr callbackPair); + void SetCallbackReference(const std::string eventType, std::shared_ptr callbackPair); void ClearCallbackReference(const std::string eventType); - void SendEvent(const std::string event, int32_t extra, const std::vector data) override; + void SendEvent(const std::string &event, int32_t extra, const std::vector &data) override; private: + struct MediaKeySystemJsCallback { + std::shared_ptr callback = nullptr; + std::string callbackName = "unknown"; + DrmEventParame eventParame; + }; + + static void WorkCallbackStateChangeDone(uv_work_t *work, int status); + static void WorkCallbackInterruptDone(uv_work_t *work, int status); + void OnJsCallbackInterrupt(std::unique_ptr &jsCb); + void OnJsCallbackStateChange(std::unique_ptr &jsCb); + napi_env env_ = nullptr; std::mutex mutex_; - std::map> callbackMap_; + std::map> callbackMap_; }; } // namespace DrmStandard } // namespace OHOS diff --git a/interfaces/kits/js/drm_napi/include/media_key_system_napi.h b/interfaces/kits/js/drm_napi/include/media_key_system_napi.h index 1eb25463..b3bc4956 100644 --- a/interfaces/kits/js/drm_napi/include/media_key_system_napi.h +++ b/interfaces/kits/js/drm_napi/include/media_key_system_napi.h @@ -33,11 +33,20 @@ #include "media_key_system_impl.h" #include "media_key_system_factory_impl.h" #include "media_key_system_callback_napi.h" +#include "napi_param_utils.h" +#include "drm_error_code.h" +#include "napi_async_work.h" namespace OHOS { namespace DrmStandard { static const char MEDIA_KEY_SYSTEM_NAPI_CLASS_NAME[] = "MediaKeySystem"; +struct MediaKeySystemAsyncContext : public ContextBase { + int32_t intValue; + NapiProvisionRequest provisionRequest; + std::vector response; +}; + class MediaKeySystemNapi { public: static napi_value Init(napi_env env, napi_value exports); @@ -64,8 +73,11 @@ public: static napi_value SetEventCallback(napi_env env, napi_callback_info info); static napi_value UnsetEventCallback(napi_env env, napi_callback_info info); - void SaveEventCallbackReferrence(const std::string eventType, sptr callbackPair); + void SaveEventCallbackReferrence(const std::string eventType, std::shared_ptr callbackPair); void ClearEventCallbackReferrence(const std::string eventType); + static bool CheckMediaKeySystemStatus(MediaKeySystemNapi *napi, + std::shared_ptr context); + static bool CheckContextStatus(std::shared_ptr context); private: static napi_value MediaKeySystemNapiConstructor(napi_env env, napi_callback_info info); diff --git a/services/drm_service/BUILD.gn b/services/drm_service/BUILD.gn index 19904235..fb189850 100644 --- a/services/drm_service/BUILD.gn +++ b/services/drm_service/BUILD.gn @@ -42,6 +42,8 @@ ohos_shared_library("drm_service") { external_deps = [ "ability_base:want", + "ability_runtime:abilitykit_native", + "ability_runtime:napi_base_context", "access_token:libaccesstoken_sdk", "access_token:libprivacy_sdk", "bundle_framework:appexecfwk_base", diff --git a/services/drm_service/ipc/i_mediakeysystem_service.h b/services/drm_service/ipc/i_mediakeysystem_service.h index 05905a3d..c4b2ad1d 100644 --- a/services/drm_service/ipc/i_mediakeysystem_service.h +++ b/services/drm_service/ipc/i_mediakeysystem_service.h @@ -48,10 +48,10 @@ public: enum CertificateStatus { CERT_STATUS_PROVISIONED = 0, - CERT_STATUS_NOT_PROVISIONED = 1, - CERT_STATUS_EXPIRED = 3, - CERT_STATUS_INVALID = 4, - CERT_STATUS_UNAVAILABLE = 5, + CERT_STATUS_NOT_PROVISIONED, + CERT_STATUS_EXPIRED, + CERT_STATUS_INVALID, + CERT_STATUS_UNAVAILABLE, }; struct MetircKeyValue { diff --git a/services/drm_service/server/src/drm_host_manager.cpp b/services/drm_service/server/src/drm_host_manager.cpp index 06175fe4..6e90ed43 100644 --- a/services/drm_service/server/src/drm_host_manager.cpp +++ b/services/drm_service/server/src/drm_host_manager.cpp @@ -22,7 +22,7 @@ #include "servmgr_hdi.h" #include "drm_log.h" #include "drm_error_code.h" -#include "drm_napi_utils.h" +#include "napi_param_utils.h" #include "drm_host_manager.h" namespace OHOS { diff --git a/services/drm_service/server/src/key_session_service_callback_stub.cpp b/services/drm_service/server/src/key_session_service_callback_stub.cpp index c18282cb..ca319211 100644 --- a/services/drm_service/server/src/key_session_service_callback_stub.cpp +++ b/services/drm_service/server/src/key_session_service_callback_stub.cpp @@ -22,7 +22,7 @@ namespace DrmStandard { int32_t MediaKeySessionServiceCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { - int32_t errCode = -1; + int32_t errCode = DRM_ERROR; if (data.ReadInterfaceToken() != GetDescriptor()) { return errCode; } diff --git a/services/drm_service/server/src/key_session_service_stub.cpp b/services/drm_service/server/src/key_session_service_stub.cpp index f7e02145..17e7818f 100644 --- a/services/drm_service/server/src/key_session_service_stub.cpp +++ b/services/drm_service/server/src/key_session_service_stub.cpp @@ -366,7 +366,7 @@ int32_t MediaKeySessionServiceStub::OnRemoteRequest(uint32_t code, MessageParcel MessageOption &option) { DRM_INFO_LOG("MediaKeySessionServiceStub::OnRemoteRequest enter."); - int32_t errCode = -1; + int32_t errCode = DRM_ERROR; DRM_DEBUG_LOG("OnRemoteRequest, cmd = %{public}u", code); DRM_DEBUG_LOG("0x%{public}06" PRIXPTR " is keySessionServiceStub", FAKE_POINTER(this)); diff --git a/services/drm_service/server/src/mediakeysystem_service_callback_stub.cpp b/services/drm_service/server/src/mediakeysystem_service_callback_stub.cpp index fd25a6ca..a541fada 100644 --- a/services/drm_service/server/src/mediakeysystem_service_callback_stub.cpp +++ b/services/drm_service/server/src/mediakeysystem_service_callback_stub.cpp @@ -23,7 +23,7 @@ namespace DrmStandard { int32_t MeidaKeySystemServiceCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { - int32_t errCode = -1; + int32_t errCode = DRM_ERROR; if (data.ReadInterfaceToken() != GetDescriptor()) { return errCode; diff --git a/services/utils/include/drm_error_code.h b/services/utils/include/drm_error_code.h index 3cd7edf4..97300e56 100644 --- a/services/utils/include/drm_error_code.h +++ b/services/utils/include/drm_error_code.h @@ -15,29 +15,39 @@ #ifndef DRM_ERROR_CODE_H #define DRM_ERROR_CODE_H +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" namespace OHOS { namespace DrmStandard { -/** - * @brief drm remote request code for IPC. - * - * @since 1.0 - * @version 1.0 - */ -enum DrmErrorCode { - DRM_ERROR = -1, - DRM_OK = 0, - DRM_ALLOC_ERROR, - DRM_INVALID_ARG, - DRM_UNSUPPORTED, - DRM_INVALID_SESSION_CFG, - DRM_INVALID_STATE, - DRM_UNKNOWN_ERROR, - DRM_OPERATION_NOT_ALLOWED, - DRM_HOST_ERROR, - DRM_SERVICE_ERROR, - DRM_MEMORY_ERROR, +class NapiDrmError { +public: + static napi_status ThrowError(napi_env env, const char *napiMessage, int32_t napiCode); + static void ThrowError(napi_env env, int32_t code); + static std::string GetMessageByCode(int32_t &code); }; + +const int32_t DRM_ERROR = -1; +const int32_t DRM_OK = 0; +const int32_t DRM_ALLOC_ERROR = 1; +const int32_t DRM_INVALID_ARG = 2; +const int32_t DRM_INVALID_STATE = 3; +const int32_t DRM_OPERATION_NOT_ALLOWED = 5; +const int32_t DRM_HOST_ERROR = 6; +const int32_t DRM_SERVICE_ERROR = 7; +const int32_t DRM_MEMORY_ERROR = 8; +const int32_t DRM_UNKNOWN_ERROR = 24700101; +const int32_t DRM_MAX_SYSTEM_NUM_REACHED = 24700103; +const int32_t DRM_MAX_SESSION_NUM_REACHED = 24700104; +const int32_t DRM_SERVICE_FATAL_ERROR = 24700201; +const int32_t DRM_INVALID_PARAM = 401; + +const std::string DRM_INVALID_PARAM_INFO = "input parameter value error"; +const std::string DRM_SERVICE_FATAL_ERRO_INFO = "service error"; +const std::string DRM_UNKNOWN_ERROR_INFO = "unknow error"; +const std::string DRM_MAX_SYSTEM_NUM_REACHED_INFO = "mediaKeySystem number limited"; +const std::string DRM_MAX_SESSION_NUM_REACHED_INFO = "mediaKeySession number limited"; } // namespace DrmStandard } // namespace OHOS #endif // DRM_ERROR_CODE_H \ No newline at end of file diff --git a/services/utils/include/drm_napi_utils.h b/services/utils/include/drm_napi_utils.h deleted file mode 100644 index 18461a2a..00000000 --- a/services/utils/include/drm_napi_utils.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef DRM_NAPI_UTILS_H -#define DRM_NAPI_UTILS_H - -#include -#include "drm_error_code.h" -#include "drm_log.h" -#include "napi/native_api.h" -#include "napi/native_node_api.h" - -#define DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar) \ - do { \ - void *data; \ - napi_get_cb_info(env, info, &(argc), argv, &(thisVar), &data); \ - } while (0) - -#define DRM_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar) \ - do { \ - void *data; \ - status = napi_get_cb_info(env, info, nullptr, nullptr, &(thisVar), &data); \ - } while (0) - -#define DRM_NAPI_GET_JS_ASYNC_CB_REF(env, arg, count, cbRef) \ - do { \ - napi_valuetype valueType = napi_undefined; \ - napi_typeof(env, arg, &valueType); \ - if (valueType == napi_function) { \ - napi_create_reference(env, arg, count, &(cbRef)); \ - } else { \ - NAPI_ASSERT(env, false, "type mismatch"); \ - } \ - } while (0) - -#define DRM_NAPI_ASSERT_NULLPTR_CHECK(env, result) \ - do { \ - if ((result) == nullptr) { \ - napi_get_undefined(env, &(result)); \ - return result; \ - } \ - } while (0) - -#define DRM_NAPI_CREATE_PROMISE(env, callbackRef, deferred, result) \ - do { \ - if ((callbackRef) == nullptr) { \ - napi_create_promise(env, &(deferred), &(result)); \ - } \ - } while (0) - -#define DRM_NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName) \ - do { \ - napi_create_string_utf8(env, resourceName, NAPI_AUTO_LENGTH, &(resource)); \ - } while (0) - -#define DRM_NAPI_CHECK_NULL_PTR_RETURN_UNDEFINED(env, ptr, ret, message) \ - do { \ - if ((ptr) == nullptr) { \ - HiLog::Error(LABEL, message); \ - napi_get_undefined(env, &(ret)); \ - return ret; \ - } \ - } while (0) - -#define DRM_NAPI_CHECK_NULL_PTR_RETURN_VOID(ptr, message) \ - do { \ - if ((ptr) == nullptr) { \ - HiLog::Error(LABEL, message); \ - return; \ - } \ - } while (0) - -#define DRM_NAPI_ASSERT_EQUAL(condition, errMsg) \ - do { \ - if (!(condition)) { \ - HiLog::Error(LABEL, errMsg); \ - return; \ - } \ - } while (0) - -#define DRM_NAPI_CHECK_AND_BREAK_LOG(cond, fmt, ...) \ - do { \ - if (!(cond)) { \ - DRM_ERR_LOG(fmt, ##__VA_ARGS__); \ - break; \ - } \ - } while (0) - -#define DRM_NAPI_CHECK_AND_RETURN_LOG(cond, fmt, ...) \ - do { \ - if (!(cond)) { \ - DRM_ERR_LOG(fmt, ##__VA_ARGS__); \ - return; \ - } \ - } while (0) - -namespace OHOS { -namespace DrmStandard { -/* Constants for array index */ -const int32_t PARAM0 = 0; -const int32_t PARAM1 = 1; -const int32_t PARAM2 = 2; -const int32_t PARAM3 = 3; - -/* Constants for array size */ -const int32_t ARGS_ZERO = 0; -const int32_t ARGS_ONE = 1; -const int32_t ARGS_TWO = 2; -const int32_t ARGS_THREE = 3; -const int32_t ARGS_FOUR = 4; - - -struct AsyncContext { - napi_env env; - napi_async_work work; - napi_deferred deferred; - napi_ref callbackRef; - bool status; - int32_t taskId; - int32_t errorCode; - std::string errorMsg; - std::string funcName; - bool isInvalidArgument; -}; -} // namespace DrmStandard -} // namespace OHOS -#endif /* DRM_NAPI_UTILS_H_ */ diff --git a/services/utils/include/napi_async_work.h b/services/utils/include/napi_async_work.h new file mode 100644 index 00000000..3b50e5e4 --- /dev/null +++ b/services/utils/include/napi_async_work.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef NAPI_ASYNC_WORK_H +#define NAPI_ASYNC_WORK_H + +#include +#include +#include +#include + +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" +#include "drm_error_code.h" +#include "napi_param_utils.h" + +namespace OHOS { +namespace DrmStandard { +using NapiCbInfoParser = std::function; +using NapiAsyncExecute = std::function; +using NapiAsyncComplete = std::function; + +struct ContextBase { + virtual ~ContextBase(); + void GetCbInfo(napi_env env, napi_callback_info info, NapiCbInfoParser parse = NapiCbInfoParser(), + bool sync = false); + void SignError(int32_t code); + napi_env env = nullptr; + napi_value output = nullptr; + napi_status status = napi_invalid_arg; + std::string errMessage; + int32_t errCode; + napi_value self = nullptr; + void* native = nullptr; + std::string taskName; + +private: + napi_deferred deferred = nullptr; + napi_async_work work = nullptr; + napi_ref callbackRef = nullptr; + napi_ref selfRef = nullptr; + + NapiAsyncExecute execute = nullptr; + NapiAsyncComplete complete = nullptr; + std::shared_ptr hold; /* cross thread data */ + + static constexpr size_t ARGC_MAX = 6; + + friend class NapiAsyncWork; +}; + +struct NapiWorkData { + napi_env env_; + napi_ref cb_; +}; + +struct AutoRef { + AutoRef(napi_env env, napi_ref cb) + : env_(env), cb_(cb) + { + } + ~AutoRef() + { + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(env_, &loop); + if (loop == nullptr) { + return; + } + + NapiWorkData *workData = new (std::nothrow) NapiWorkData(); + if (workData == nullptr) { + return; + } + workData->env_ = env_; + workData->cb_ = cb_; + + uv_work_t *work = new(std::nothrow) uv_work_t; + if (work == nullptr) { + delete workData; + workData = nullptr; + return; + } + work->data = (void *)workData; + + int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, [] (uv_work_t *work, int status) { + // Js thread + NapiWorkData *workData = reinterpret_cast(work->data); + napi_env env = workData->env_; + napi_ref cb = workData->cb_; + if (env != nullptr && cb != nullptr) { + (void)napi_delete_reference(env, cb); + } + delete workData; + delete work; + }, uv_qos_default); + if (ret != 0) { + delete work; + work = nullptr; + delete workData; + workData = nullptr; + } + } + napi_env env_; + napi_ref cb_; +}; + +class NapiAsyncWork { +public: + static napi_value Enqueue(napi_env env, std::shared_ptr ctxt, const std::string &name, + NapiAsyncExecute execute = NapiAsyncExecute(), + NapiAsyncComplete complete = NapiAsyncComplete()); + +private: + enum { + /* AsyncCallback / Promise output result index */ + RESULT_ERROR = 0, + RESULT_DATA = 1, + RESULT_ALL = 2 + }; + static void CommonCallbackRoutine(ContextBase *ctxt); +}; +} // namespace DrmStandard +} // namespace OHOS +#endif // NAPI_ASYNC_WORK_H \ No newline at end of file diff --git a/services/utils/include/napi_param_utils.h b/services/utils/include/napi_param_utils.h new file mode 100644 index 00000000..6c2210b2 --- /dev/null +++ b/services/utils/include/napi_param_utils.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef NAPI_PARAM_UTILS_H +#define NAPI_PARAM_UTILS_H + +#include +#include +#include +#include +#include +#include +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" +#include "napi_base_context.h" +#include "drm_log.h" +#include "drm_error_code.h" +#include "i_keysession_service.h" + +namespace OHOS { +namespace DrmStandard { +/* Constants for array index */ +const int32_t PARAM0 = 0; +const int32_t PARAM1 = 1; +const int32_t PARAM2 = 2; +const int32_t PARAM3 = 3; + +/* Constants for array size */ +const int32_t ARGS_ZERO = 0; +const int32_t ARGS_ONE = 1; +const int32_t ARGS_TWO = 2; +const int32_t ARGS_THREE = 3; +const int32_t ARGS_FOUR = 4; + +const int32_t KEY_SYSTEM_MAX_NUMBER = 64; +const int32_t KEY_SESSION_MAX_NUMBER = 64; + +enum NapiMediaKeyRequestType { + MEDIA_KEY_REQUEST_TYPE_UNKNOWN = 0, + MEDIA_KEY_REQUEST_TYPE_INITIAL, + MEDIA_KEY_REQUEST_TYPE_RENEWAL, + MEDIA_KEY_REQUEST_TYPE_RELEASE, + MEDIA_KEY_REQUEST_TYPE_NONE, + MEDIA_KEY_REQUEST_TYPE_UPDATE, +}; + +struct NapiProvisionRequest { + std::vector data; + std::string defaultURL; +}; + +struct DrmEventParame { + int32_t extra; + std::vector data; +}; + +struct DrmKeysChangeEventParame { + std::map, MediaKeySessionKeyStatus> statusTable; + bool hasNewGoodLicense; +}; + +template +class ObjectRefMap { +public: + static std::mutex allObjLock; + static std::map refMap; + static void Insert(T *obj); + static void Erase(T *obj); + static T *IncreaseRef(T *obj); + static void DecreaseRef(T *obj); + + ObjectRefMap(T *obj); + ~ObjectRefMap(); + T *GetPtr(); + +private: + T *obj_ = nullptr; +}; + +template +std::mutex ObjectRefMap::allObjLock; + +template +std::map ObjectRefMap::refMap; + +template +void ObjectRefMap::Insert(T *obj) +{ + std::lock_guard lock(allObjLock); + refMap[obj] = 1; +} + +template +void ObjectRefMap::Erase(T *obj) +{ + std::lock_guard lock(allObjLock); + auto it = refMap.find(obj); + if (it != refMap.end()) { + refMap.erase(it); + } +} + +template +T *ObjectRefMap::IncreaseRef(T *obj) +{ + std::lock_guard lock(allObjLock); + if (refMap.count(obj)) { + refMap[obj]++; + return obj; + } else { + return nullptr; + } +} + +template +void ObjectRefMap::DecreaseRef(T *obj) +{ + std::lock_guard lock(allObjLock); + if (refMap.count(obj) && --refMap[obj] == 0) { + refMap.erase(obj); + delete obj; + obj = nullptr; + } +} + +template +ObjectRefMap::ObjectRefMap(T *obj) +{ + if (obj != nullptr) { + obj_ = ObjectRefMap::IncreaseRef(obj); + } +} + +template +ObjectRefMap::~ObjectRefMap() +{ + if (obj_ != nullptr) { + ObjectRefMap::DecreaseRef(obj_); + } +} + +template +T *ObjectRefMap::GetPtr() +{ + return obj_; +} + +#define DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar) \ + do { \ + void *data; \ + napi_get_cb_info(env, info, &(argc), argv, &(thisVar), &data); \ + } while (0) + +#define DRM_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar) \ + do { \ + void *data; \ + status = napi_get_cb_info(env, info, nullptr, nullptr, &(thisVar), &data); \ + } while (0) + +#define DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(cond, fmt, ...) \ + do { \ + if (!(cond)) { \ + DRM_ERR_LOG(fmt, ##__VA_ARGS__); \ + return; \ + } \ + } while (0) + +#define DRM_NAPI_CHECK_AND_RETURN_LOG(cond, status, fmt, ...) \ + do { \ + if (!(cond)) { \ + DRM_ERR_LOG(fmt, ##__VA_ARGS__); \ + return status; \ + } \ + } while (0) + + +/* check condition related to argc/argv, return and logging. */ +#define NAPI_CHECK_ARGS_RETURN_VOID(context, condition, message, code) \ + do { \ + if (!(condition)) { \ + (context)->status = napi_invalid_arg; \ + (context)->errMessage = std::string(message); \ + (context)->errCode = code; \ + DRM_ERR_LOG("test (" #condition ") failed: " message); \ + return; \ + } \ + } while (0) + +#define NAPI_CHECK_STATUS_RETURN_VOID(context, message, code) \ + do { \ + if ((context)->status != napi_ok) { \ + (context)->errMessage = std::string(message); \ + (context)->errCode = code; \ + DRM_ERR_LOG("test (context->status == napi_ok) failed: " message); \ + return; \ + } \ + } while (0) + +class NapiParamUtils { +public: + static napi_status GetValueInt32(const napi_env &env, int32_t &value, napi_value in); + static napi_status SetValueInt32(const napi_env &env, const int32_t &value, napi_value &result); + static napi_status GetValueInt32(const napi_env &env, const std::string &fieldStr, int32_t &value, napi_value in); + static napi_status SetValueInt32(const napi_env &env, const std::string &fieldStr, + const int32_t value, napi_value &result); + + static std::string GetStringArgument(napi_env env, napi_value value); + static napi_status SetValueString(const napi_env &env, const std::string &stringValue, napi_value &result); + static napi_status SetValueString(const napi_env &env, const std::string &fieldStr, const std::string &stringValue, + napi_value &result); + + static napi_value GetUndefinedValue(napi_env env); + + static napi_status SetValueUint8Array(const napi_env &env, const std::vector &value, + napi_value &result); + static napi_status SetValueUint8Array(const napi_env &env, const std::string &fieldStr, + const std::vector &value, napi_value &result); + static napi_status GetValueUint8Array(const napi_env &env, std::vector &value, + napi_value in); + static napi_status SetValueBoolean(const napi_env &env, const bool boolValue, napi_value &result); + static napi_status SetValueMap(const napi_env &env, + std::map, MediaKeySessionKeyStatus> statusTable, napi_value &result); + + static napi_status GetValueOptionsData(const napi_env &env, std::map &valueMap, + napi_value in); + static napi_status SetProvisionRequest(const napi_env &env, const NapiProvisionRequest &provisionRequest, + napi_value &result); + static napi_status SetMediaKeyRequest(const napi_env &env, + const IMediaKeySessionService::MediaKeyRequest &mediaKeyRequest, napi_value &result); + static napi_status SetDrmEventInfo(const napi_env &env, DrmEventParame &eventParame, + napi_value &result); + static napi_status SetDrmKeysChangeEventInfo(const napi_env &env, DrmKeysChangeEventParame &eventParame, + napi_value &statusTable, napi_value &hasNewGoodLicense); +}; +} // namespace DrmStandard +} // namespace OHOS +#endif // NAPI_PARAM_UTILS_H