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 "key_session_callback_napi.h"
17
18 namespace OHOS {
19 namespace DrmStandard {
MediaKeySessionCallbackNapi(napi_env env)20 MediaKeySessionCallbackNapi::MediaKeySessionCallbackNapi(napi_env env)
21 {
22 env_ = env;
23 }
24
~MediaKeySessionCallbackNapi()25 MediaKeySessionCallbackNapi::~MediaKeySessionCallbackNapi() {}
26
SetCallbackReference(const std::string eventType,std::shared_ptr<AutoRef> callbackPair)27 void MediaKeySessionCallbackNapi::SetCallbackReference(const std::string eventType,
28 std::shared_ptr<AutoRef> callbackPair)
29 {
30 DRM_INFO_LOG("MediaKeySessionCallbackNapi SetCallbackReference");
31 std::lock_guard<std::mutex> lock(mutex_);
32 callbackMap_[eventType] = callbackPair;
33 }
34
ClearCallbackReference(const std::string eventType)35 void MediaKeySessionCallbackNapi::ClearCallbackReference(const std::string eventType)
36 {
37 DRM_INFO_LOG("MediaKeySessionCallbackNapi 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 MediaKeySessionCallbackNapi::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<MediaKeySessionJsCallback> cb = std::make_unique<MediaKeySessionJsCallback>();
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<MediaKeySessionJsCallback> & jsCb)54 void MediaKeySessionCallbackNapi::OnJsCallbackInterrupt(std::unique_ptr<MediaKeySessionJsCallback> &jsCb)
55 {
56 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(jsCb.get() != nullptr, "OnJsCallbackInterrupt: jsCb.get() is null");
57 MediaKeySessionJsCallback *event = jsCb.get();
58 auto task = [event]() {
59 std::shared_ptr<MediaKeySessionJsCallback> context(static_cast<MediaKeySessionJsCallback*>(event),
60 [](MediaKeySessionJsCallback* ptr) {
61 delete ptr;
62 });
63 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(event != nullptr, "event is nullptr");
64 std::string request = event->callbackName;
65
66 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(event->callback != nullptr, "event is nullptr");
67 napi_env env = event->callback->env_;
68 napi_ref callback = event->callback->cb_;
69
70 napi_handle_scope scope = nullptr;
71 napi_open_handle_scope(env, &scope);
72 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(scope != nullptr, "scope is nullptr");
73 DRM_DEBUG_LOG("JsCallBack %{public}s, dowork", request.c_str());
74 do {
75 napi_value jsCallback = nullptr;
76 napi_status nstatus = napi_get_reference_value(env, callback, &jsCallback);
77 DRM_NAPI_CHECK_AND_CLOSE_RETURN_VOID_LOG(nstatus == napi_ok && jsCallback != nullptr,
78 "%{public}s get reference value fail", request.c_str());
79 napi_value result = nullptr;
80 if (event->callbackName == "keysChange") {
81 napi_value statusTable;
82 napi_value hasNewGoodLicense;
83 nstatus = NapiParamUtils::SetDrmKeysChangeEventInfo(env, event->keysChangeParame,
84 statusTable, hasNewGoodLicense);
85 DRM_NAPI_CHECK_AND_CLOSE_RETURN_VOID_LOG(nstatus == napi_ok,
86 "%{public}s fail to create keysession keyschange callback", request.c_str());
87 napi_value args[ARGS_TWO] = { statusTable, hasNewGoodLicense };
88 nstatus = napi_call_function(env, nullptr, jsCallback, ARGS_TWO, args, &result);
89 DRM_NAPI_CHECK_AND_CLOSE_RETURN_VOID_LOG(nstatus == napi_ok,
90 "%{public}s fail to call Interrupt callback", request.c_str());
91 } else {
92 napi_value args[ARGS_ONE] = { nullptr };
93 nstatus = NapiParamUtils::SetDrmEventInfo(env, event->eventParame, args[PARAM0]);
94 DRM_NAPI_CHECK_AND_CLOSE_RETURN_VOID_LOG(nstatus == napi_ok && args[PARAM0] != nullptr,
95 "%{public}s fail to create keysession callback", request.c_str());
96 nstatus = napi_call_function(env, nullptr, jsCallback, ARGS_ONE, args, &result);
97 DRM_NAPI_CHECK_AND_CLOSE_RETURN_VOID_LOG(nstatus == napi_ok,
98 "%{public}s fail to call Interrupt callback", request.c_str());
99 }
100 } while (0);
101 napi_close_handle_scope(env, scope);
102 };
103 if (napi_status::napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
104 DRM_ERR_LOG("OnJsCallbackInterrupt: Failed to SendEvent");
105 } else {
106 jsCb.release();
107 }
108 }
109
SendEventKeyChanged(std::map<std::vector<uint8_t>,MediaKeySessionKeyStatus> statusTable,bool hasNewGoodLicense)110 void MediaKeySessionCallbackNapi::SendEventKeyChanged(
111 std::map<std::vector<uint8_t>, MediaKeySessionKeyStatus> statusTable, bool hasNewGoodLicense)
112 {
113 std::lock_guard<std::mutex> lock(mutex_);
114 std::unique_ptr<MediaKeySessionJsCallback> cb = std::make_unique<MediaKeySessionJsCallback>();
115 DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(cb != nullptr, "No memory");
116 const std::string event = "keysChange";
117 cb->callback = callbackMap_[event];
118 cb->callbackName = event;
119 cb->keysChangeParame.hasNewGoodLicense = hasNewGoodLicense;
120 cb->keysChangeParame.statusTable = statusTable;
121 return OnJsCallbackInterrupt(cb);
122 }
123 } // DrmStandardr
124 } // OHOS