1 /*
2  * Copyright (C) 2023  Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <map>
17 #include <vector>
18 #include "napi_param_utils.h"
19 #include "drm_enum_napi.h"
20 
21 namespace OHOS {
22 namespace DrmStandard {
23 struct JsEnumInt {
24     std::string_view enumName;
25     int32_t enumInt;
26 };
27 
28 struct JsEnumString {
29     std::string_view enumName;
30     std::string_view enumString;
31 };
32 
33 static const std::vector<struct JsEnumInt> g_listenerType = {
34     { "LISTENER_DRM_EVENT", IMediaKeySessionService::ListenerType::LISTENER_DRM_EVENT },
35     { "LISTENER_PROVISION_REQUIRED", IMediaKeySessionService::ListenerType::LISTENER_PROVISION_REQUIRED },
36     { "LISTENER_KEY_REQUIRED", IMediaKeySessionService::ListenerType::LISTENER_KEY_REQUIRED },
37     { "LISTENER_KEY_EXPIRED", IMediaKeySessionService::ListenerType::LISTENER_KEY_EXPIRED },
38     { "LISTENER_VENDOR_DEFINED", IMediaKeySessionService::ListenerType::LISTENER_VENDOR_DEFINED },
39     { "LISTENER_EXPIRATION_UPDATE", IMediaKeySessionService::ListenerType::LISTENER_EXPIRATION_UPDATE },
40     { "LISTENER_KEY_CHANGE", IMediaKeySessionService::ListenerType::LISTENER_KEY_CHANGE },
41 };
42 
43 static const std::vector<struct JsEnumInt> g_mediaKeyType = {
44     { "MEDIA_KEY_TYPE_OFFLINE", IMediaKeySessionService::MediaKeyType::LICENSETYPE_OFFLINE },
45     { "MEDIA_KEY_TYPE_ONLINE", IMediaKeySessionService::MediaKeyType::LICENSETYPE_ONLINE },
46 };
47 
48 static const std::vector<struct JsEnumInt> g_offlineMediaKeyStatus = {
49     { "OFFLINE_MEDIA_KEY_STATUS_UNKNOWN",
50       IMediaKeySessionService::OfflineMediaKeyStatus::OFFLINELICENSESTATUS_UNKNOWN },
51     { "OFFLINE_MEDIA_KEY_STATUS_USABLE",
52       IMediaKeySessionService::OfflineMediaKeyStatus::OFFLINELICENSESTATUS_USABLE },
53     { "OFFLINE_MEDIA_KEY_STATUS_INACTIVE",
54       IMediaKeySessionService::OfflineMediaKeyStatus::OFFLINELICENSESTATUS_INACTIVE },
55 };
56 
57 static const std::vector<struct JsEnumInt> g_certificateStatus = {
58     { "CERT_STATUS_PROVISIONED", IMediaKeySystemService::CertificateStatus::CERT_STATUS_PROVISIONED },
59     { "CERT_STATUS_NOT_PROVISIONED", IMediaKeySystemService::CertificateStatus::CERT_STATUS_NOT_PROVISIONED },
60     { "CERT_STATUS_EXPIRED", IMediaKeySystemService::CertificateStatus::CERT_STATUS_EXPIRED },
61     { "CERT_STATUS_INVALID", IMediaKeySystemService::CertificateStatus::CERT_STATUS_INVALID },
62     { "CERT_STATUS_UNAVAILABLE", IMediaKeySystemService::CertificateStatus::CERT_STATUS_UNAVAILABLE },
63 };
64 
65 static const std::vector<struct JsEnumInt> g_mediaKeyRequestType = {
66     { "MEDIA_KEY_REQUEST_TYPE_UNKNOWN", IMediaKeySessionService::RequestType::REQUEST_TYPE_UNKNOWN },
67     { "MEDIA_KEY_REQUEST_TYPE_INITIAL", IMediaKeySessionService::RequestType::REQUEST_TYPE_INITIAL },
68     { "MEDIA_KEY_REQUEST_TYPE_RENEWAL", IMediaKeySessionService::RequestType::REQUEST_TYPE_RENEWAL },
69     { "MEDIA_KEY_REQUEST_TYPE_RELEASE", IMediaKeySessionService::RequestType::REQUEST_TYPE_RELEASE },
70     { "MEDIA_KEY_REQUEST_TYPE_NONE", IMediaKeySessionService::RequestType::REQUEST_TYPE_NONE },
71     { "MEDIA_KEY_REQUEST_TYPE_UPDATE", IMediaKeySessionService::RequestType::REQUEST_TYPE_UPDATE },
72 };
73 
74 static const std::vector<struct JsEnumInt> g_drmErrorCode = {
75     { "ERROR_UNKNOWN", 24700101 },
76     { "MAX_SYSTEM_NUM_REACHED", 24700103 },
77     { "MAX_SESSION_NUM_REACHED", 24700104 },
78     { "SERVICE_FATAL_ERROR", 24700201 },
79 };
80 
81 static const std::vector<struct JsEnumInt> g_contentProtectionLevel = {
82     { "CONTENT_PROTECTION_LEVEL_UNKNOWN",
83         IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_UNKNOWN },
84     { "CONTENT_PROTECTION_LEVEL_SW_CRYPTO",
85         IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_SW_CRYPTO },
86     { "CONTENT_PROTECTION_LEVEL_HW_CRYPTO",
87         IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_HW_CRYPTO },
88     { "CONTENT_PROTECTION_LEVEL_ENHANCED_HW",
89         IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_ENHANCED_HW },
90     { "CONTENT_PROTECTION_LEVEL_MAX",
91         IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_MAX },
92 };
93 
94 static const std::vector<struct JsEnumString> g_preDefinedConfigName = {
95     { "CONFIG_DEVICE_VENDOR", "vendor" },
96     { "CONFIG_DEVICE_VERSION", "version" },
97     { "CONFIG_DEVICE_DESCRIPTION", "description" },
98     { "CONFIG_DEVICE_ALGORITHMS", "algorithms" },
99     { "CONFIG_DEVICE_UNIQUE_ID", "deviceUniqueId" },
100     { "CONFIG_SESSION_MAX", "maxSessionNum" },
101     { "CONFIG_SESSION_CURRENT", "currentSessionNum" },
102 };
103 
104 static const std::map<std::string_view, const std::vector<struct JsEnumInt> &> g_intEnumClassMap = {
105     { "ListenerType", g_listenerType },
106     { "MediaKeyType", g_mediaKeyType },
107     { "OfflineMediaKeyStatus", g_offlineMediaKeyStatus },
108     { "CertificateStatus", g_certificateStatus },
109     { "MediaKeyRequestType", g_mediaKeyRequestType },
110     { "DrmErrorCode", g_drmErrorCode },
111     { "ContentProtectionLevel", g_contentProtectionLevel },
112 };
113 
114 static const std::map<std::string_view, const std::vector<struct JsEnumString> &> g_stringEnumClassMap = {
115     { "PreDefinedConfigName", g_preDefinedConfigName },
116 };
117 
JsEnumIntInit(napi_env env,napi_value exports)118 napi_value DrmEnumNapi::JsEnumIntInit(napi_env env, napi_value exports)
119 {
120     for (auto it = g_intEnumClassMap.begin(); it != g_intEnumClassMap.end(); it++) {
121         auto &enumClassName = it->first;
122         auto &enumItemVec = it->second;
123         uint32_t vecSize = enumItemVec.size();
124         std::vector<napi_value> value;
125         value.resize(vecSize);
126         for (uint32_t index = 0; index < vecSize; ++index) {
127             napi_create_int32(env, enumItemVec[index].enumInt, &value[index]);
128         }
129 
130         std::vector<napi_property_descriptor> property;
131         property.resize(vecSize);
132         for (uint32_t index = 0; index < vecSize; ++index) {
133             property[index] =
134                 napi_property_descriptor DECLARE_NAPI_STATIC_PROPERTY(enumItemVec[index].enumName.data(), value[index]);
135         }
136 
137         auto constructor = [](napi_env env, napi_callback_info info) {
138             napi_value jsThis = nullptr;
139             napi_get_cb_info(env, info, nullptr, nullptr, &jsThis, nullptr);
140             return jsThis;
141         };
142 
143         napi_value result = nullptr;
144         napi_status status = napi_define_class(env, enumClassName.data(), NAPI_AUTO_LENGTH, constructor, nullptr,
145             property.size(), property.data(), &result);
146         DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define enum");
147 
148         status = napi_set_named_property(env, exports, enumClassName.data(), result);
149         DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to set result");
150     }
151     return exports;
152 }
153 
JsEnumStringInit(napi_env env,napi_value exports)154 napi_value DrmEnumNapi::JsEnumStringInit(napi_env env, napi_value exports)
155 {
156     for (auto it = g_stringEnumClassMap.begin(); it != g_stringEnumClassMap.end(); it++) {
157         auto &enumClassName = it->first;
158         auto &enumItemVec = it->second;
159         uint32_t vecSize = enumItemVec.size();
160         std::vector<napi_value> value;
161         value.resize(vecSize);
162         for (uint32_t index = 0; index < vecSize; ++index) {
163             napi_create_string_utf8(env, enumItemVec[index].enumString.data(), NAPI_AUTO_LENGTH, &value[index]);
164         }
165 
166         std::vector<napi_property_descriptor> property;
167         property.resize(vecSize);
168         for (uint32_t index = 0; index < vecSize; ++index) {
169             property[index] =
170                 napi_property_descriptor DECLARE_NAPI_STATIC_PROPERTY(enumItemVec[index].enumName.data(), value[index]);
171         }
172 
173         auto constructor = [](napi_env env, napi_callback_info info) {
174             napi_value jsThis = nullptr;
175             napi_get_cb_info(env, info, nullptr, nullptr, &jsThis, nullptr);
176             return jsThis;
177         };
178 
179         napi_value result = nullptr;
180         napi_status status = napi_define_class(env, enumClassName.data(), NAPI_AUTO_LENGTH, constructor, nullptr,
181             property.size(), property.data(), &result);
182         DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define enum");
183 
184         status = napi_set_named_property(env, exports, enumClassName.data(), result);
185         DRM_CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to set result");
186     }
187     return exports;
188 }
189 
Init(napi_env env,napi_value exports)190 napi_value DrmEnumNapi::Init(napi_env env, napi_value exports)
191 {
192     JsEnumIntInit(env, exports);
193     JsEnumStringInit(env, exports);
194     return exports;
195 }
196 } // namespace drm
197 } // namespace OHOS
198