• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 "screen_capture_monitor_callback.h"
16 #include "screen_capture_monitor_napi.h"
17 #include "media_log.h"
18 #include "scope_guard.h"
19 
20 namespace {
21     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_RECORDER, "ScreenCaptureMonitorCallback"};
22 }
23 
24 namespace OHOS {
25 namespace Media {
ScreenCaptureMonitorCallback(napi_env env)26 ScreenCaptureMonitorCallback::ScreenCaptureMonitorCallback(napi_env env) : env_(env)
27 {
28     MEDIA_LOGI("0x%{public}06" PRIXPTR "Instances create", FAKE_POINTER(this));
29 }
30 
~ScreenCaptureMonitorCallback()31 ScreenCaptureMonitorCallback::~ScreenCaptureMonitorCallback()
32 {
33     MEDIA_LOGI("0x%{public}06" PRIXPTR "Instances destroy", FAKE_POINTER(this));
34 }
35 
SaveCallbackReference(const std::string & name,std::weak_ptr<AutoRef> ref)36 void ScreenCaptureMonitorCallback::SaveCallbackReference(const std::string &name, std::weak_ptr<AutoRef> ref)
37 {
38     std::lock_guard<std::mutex> lock(mutex_);
39     refMap_[name] = ref;
40     MEDIA_LOGI("Set callback type: %{public}s", name.c_str());
41 }
42 
CancelCallbackReference(const std::string & name)43 void ScreenCaptureMonitorCallback::CancelCallbackReference(const std::string &name)
44 {
45     std::lock_guard<std::mutex> lock(mutex_);
46     auto iter = refMap_.find(name);
47     if (iter != refMap_.end()) {
48         refMap_.erase(iter);
49     }
50     MEDIA_LOGI("Cancel callback type: %{public}s", name.c_str());
51 }
52 
OnScreenCaptureStarted(int32_t pid)53 void ScreenCaptureMonitorCallback::OnScreenCaptureStarted(int32_t pid)
54 {
55     MEDIA_LOGI("OnScreenCaptureStarted S %{public}d", pid);
56     std::lock_guard<std::mutex> lock(mutex_);
57     if (refMap_.find(EVENT_SYSTEM_SCREEN_RECORD) == refMap_.end()) {
58         MEDIA_LOGW("can not find systemScreenRecorder callback!");
59         return;
60     }
61 
62     bool shouldSendCb = ScreenCaptureMonitor::GetInstance()->IsSystemScreenRecorder(pid);
63     if (!shouldSendCb) {
64         MEDIA_LOGW("pid not match, do not send callback!");
65         return;
66     }
67 
68     ScreenCaptureMonitorJsCallback *cb = new(std::nothrow) ScreenCaptureMonitorJsCallback();
69     CHECK_AND_RETURN_LOG(cb != nullptr, "cb is nullptr");
70     cb->autoRef = refMap_.at(EVENT_SYSTEM_SCREEN_RECORD);
71     cb->callbackName = EVENT_SYSTEM_SCREEN_RECORD;
72     cb->captureEvent = ScreenCaptureMonitorEvent::SCREENCAPTURE_STARTED;
73     MEDIA_LOGI("OnScreenCaptureStarted E");
74     return OnJsCaptureCallBack(cb);
75 }
76 
OnScreenCaptureFinished(int32_t pid)77 void ScreenCaptureMonitorCallback::OnScreenCaptureFinished(int32_t pid)
78 {
79     MEDIA_LOGI("OnScreenCaptureFinished S %{public}d", pid);
80     std::lock_guard<std::mutex> lock(mutex_);
81     if (refMap_.find(EVENT_SYSTEM_SCREEN_RECORD) == refMap_.end()) {
82         MEDIA_LOGW("can not find systemScreenRecorder callback!");
83         return;
84     }
85 
86     bool shouldSendCb = ScreenCaptureMonitor::GetInstance()->IsSystemScreenRecorder(pid);
87     if (!shouldSendCb) {
88         MEDIA_LOGW("pid not match, do not send callback!");
89         return;
90     }
91 
92     ScreenCaptureMonitorJsCallback *cb = new(std::nothrow) ScreenCaptureMonitorJsCallback();
93     CHECK_AND_RETURN_LOG(cb != nullptr, "cb is nullptr");
94     cb->autoRef = refMap_.at(EVENT_SYSTEM_SCREEN_RECORD);
95     cb->callbackName = EVENT_SYSTEM_SCREEN_RECORD;
96     cb->captureEvent = ScreenCaptureMonitorEvent::SCREENCAPTURE_STOPPED;
97     MEDIA_LOGI("OnScreenCaptureFinished E");
98     return OnJsCaptureCallBack(cb);
99 }
100 
OnJsCaptureCallBack(ScreenCaptureMonitorJsCallback * jsCb) const101 void ScreenCaptureMonitorCallback::OnJsCaptureCallBack(ScreenCaptureMonitorJsCallback *jsCb) const
102 {
103     ON_SCOPE_EXIT(0) {
104         delete jsCb;
105     };
106 
107     auto task = [jsCb]() {
108         std::string request = jsCb->callbackName;
109         do {
110             std::shared_ptr<AutoRef> ref = jsCb->autoRef.lock();
111             CHECK_AND_BREAK_LOG(ref != nullptr, "%{public}s AutoRef is nullptr", request.c_str());
112 
113             napi_handle_scope scope = nullptr;
114             napi_open_handle_scope(ref->env_, &scope);
115             CHECK_AND_BREAK_LOG(scope != nullptr, "%{public}s scope is nullptr", request.c_str());
116             ON_SCOPE_EXIT(0) {
117                 napi_close_handle_scope(ref->env_, scope);
118             };
119 
120             napi_value jsCallback = nullptr;
121             napi_status nstatus = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
122             CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "%{public}s get reference value fail",
123                 request.c_str());
124 
125             napi_value args[1] = { nullptr };
126             nstatus = napi_create_int32(ref->env_, jsCb->captureEvent, &args[0]);
127             CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[0] != nullptr,
128                 "%{public}s fail to create callback", request.c_str());
129 
130             const size_t argCount = 1;
131             napi_value result = nullptr;
132             nstatus = napi_call_function(ref->env_, nullptr, jsCallback, argCount, args, &result);
133             CHECK_AND_BREAK_LOG(nstatus == napi_ok, "%{public}s fail to napi call function", request.c_str());
134         } while (0);
135         delete jsCb;
136     };
137     CHECK_AND_RETURN_LOG(napi_send_event(env_, task, napi_eprio_immediate) == napi_status::napi_ok,
138         "OnJsCaptureCallBack napi_send_event failed");
139 
140     CANCEL_SCOPE_EXIT_GUARD(0);
141 }
142 } // namespace Media
143 } // namespace OHOS