1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "drm_log.h"
16 #include "media_key_system_callback_napi.h"
17
18 namespace OHOS {
19 namespace DrmStandard {
MediaKeySystemCallbackNapi(napi_env env)20 MediaKeySystemCallbackNapi::MediaKeySystemCallbackNapi(napi_env env)
21 {
22 env_ = env;
23 }
24
~MediaKeySystemCallbackNapi()25 MediaKeySystemCallbackNapi::~MediaKeySystemCallbackNapi() {}
26
SetCallbackReference(const std::string eventType,std::shared_ptr<AutoRef> callbackPair)27 void MediaKeySystemCallbackNapi::SetCallbackReference(const std::string eventType,
28 std::shared_ptr<AutoRef> callbackPair)
29 {
30 DRM_INFO_LOG("MediaKeySystemCallbackNapi SetCallbackReference");
31 std::lock_guard<std::mutex> lock(mutex_);
32 callbackMap_[eventType] = callbackPair;
33 }
34
ClearCallbackReference(const std::string eventType)35 void MediaKeySystemCallbackNapi::ClearCallbackReference(const std::string eventType)
36 {
37 DRM_INFO_LOG("MediaKeySystemCallbackNapi ClearCallbackReference");
38 std::lock_guard<std::mutex> lock(mutex_);
39 callbackMap_.erase(eventType);
40 }
41
SendEvent(const std::string & event,int32_t extra,const std::vector<uint8_t> & data)42 void MediaKeySystemCallbackNapi::SendEvent(const std::string &event, int32_t extra, const std::vector<uint8_t> &data)
43 {
44 std::lock_guard<std::mutex> lock(mutex_);
45 std::unique_ptr<MediaKeySystemJsCallback> cb = std::make_unique<MediaKeySystemJsCallback>();
46 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(cb != nullptr, "No memory");
47 cb->callback = callbackMap_[event];
48 cb->callbackName = event;
49 cb->eventParame.extra = extra;
50 cb->eventParame.data.assign(data.begin(), data.end());
51 return OnJsCallbackInterrupt(cb);
52 }
53
OnJsCallbackInterrupt(std::unique_ptr<MediaKeySystemJsCallback> & jsCb)54 void MediaKeySystemCallbackNapi::OnJsCallbackInterrupt(std::unique_ptr<MediaKeySystemJsCallback> &jsCb)
55 {
56 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(jsCb.get() != nullptr, "OnJsCallbackInterrupt: jsCb.get() is null");
57 MediaKeySystemJsCallback *event = jsCb.get();
58 auto task = [event]() {
59 std::shared_ptr<MediaKeySystemJsCallback> context(
60 static_cast<MediaKeySystemJsCallback*>(event),
61 [](MediaKeySystemJsCallback* ptr) {
62 delete ptr;
63 });
64
65 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(event != nullptr, "event is nullptr");
66 std::string request = event->callbackName;
67
68 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(event->callback != nullptr, "event is nullptr");
69 napi_env env = event->callback->env_;
70 napi_ref callback = event->callback->cb_;
71
72 napi_handle_scope scope = nullptr;
73 napi_open_handle_scope(env, &scope);
74 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(scope != nullptr, "scope is nullptr");
75 DRM_DEBUG_LOG("JsCallBack %{public}s, doWork", request.c_str());
76 do {
77 napi_value jsCallback = nullptr;
78 napi_status nstatus = napi_get_reference_value(env, callback, &jsCallback);
79 DRM_NAPI_CHECK_AND_CLOSE_RETURN_VOID_LOG(nstatus == napi_ok && jsCallback != nullptr,
80 "%{public}s get reference value fail", request.c_str());
81
82 napi_value args[ARGS_ONE] = { nullptr };
83 nstatus = NapiParamUtils::SetDrmEventInfo(env, event->eventParame, args[PARAM0]);
84 DRM_NAPI_CHECK_AND_CLOSE_RETURN_VOID_LOG(nstatus == napi_ok && args[PARAM0] != nullptr,
85 "%{public}s fail to create keysystem callback", request.c_str());
86
87 const size_t argCount = ARGS_ONE;
88 napi_value result = nullptr;
89 nstatus = napi_call_function(env, nullptr, jsCallback, argCount, args, &result);
90 DRM_NAPI_CHECK_AND_CLOSE_RETURN_VOID_LOG(nstatus == napi_ok, "%{public}s fail to call Interrupt callback",
91 request.c_str());
92 } while (0);
93 napi_close_handle_scope(env, scope);
94 };
95 if (napi_status::napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
96 DRM_ERR_LOG("OnJsCallbackInterrupt: Failed to SendEvent");
97 } else {
98 jsCb.release();
99 }
100 }
101 } // namespace DrmStandard
102 } // namespace OHOS