1 /*
2 * Copyright (c) 2024 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 "ipc_callbacks/rs_surface_buffer_callback.h"
17 #include "pipeline/rs_surface_buffer_callback_manager.h"
18 #include "platform/common/rs_log.h"
19
20 namespace OHOS {
21 namespace Rosen {
Instance()22 RSSurfaceBufferCallbackManager& RSSurfaceBufferCallbackManager::Instance()
23 {
24 static RSSurfaceBufferCallbackManager surfaceBufferCallbackMgr;
25 return surfaceBufferCallbackMgr;
26 }
27
SetRunPolicy(std::function<void (std::function<void ()>)> runPolicy)28 void RSSurfaceBufferCallbackManager::SetRunPolicy(std::function<void(std::function<void()>)> runPolicy)
29 {
30 runPolicy_ = runPolicy;
31 }
32
RegisterSurfaceBufferCallback(pid_t pid,uint64_t uid,sptr<RSISurfaceBufferCallback> callback)33 void RSSurfaceBufferCallbackManager::RegisterSurfaceBufferCallback(pid_t pid, uint64_t uid,
34 sptr<RSISurfaceBufferCallback> callback)
35 {
36 std::unique_lock<std::shared_mutex> lock { registerSurfaceBufferCallbackMutex_ };
37 auto iter = surfaceBufferCallbacks_.find({pid, uid});
38 if (iter == std::end(surfaceBufferCallbacks_)) {
39 surfaceBufferCallbacks_.insert({{pid, uid}, callback});
40 } else {
41 RS_LOGE("RSSurfaceBufferCallbackManager::RegisterSurfaceBufferCallback Pair:"
42 "[Pid: %{public}s, Uid: %{public}s] exists.",
43 std::to_string(pid).c_str(), std::to_string(uid).c_str());
44 }
45 }
46
UnregisterSurfaceBufferCallback(pid_t pid)47 void RSSurfaceBufferCallbackManager::UnregisterSurfaceBufferCallback(pid_t pid)
48 {
49 std::unique_lock<std::shared_mutex> lock { registerSurfaceBufferCallbackMutex_ };
50 EraseIf(surfaceBufferCallbacks_, [pid](auto& pair) {
51 return pair.first.first == pid;
52 });
53 }
54
UnregisterSurfaceBufferCallback(pid_t pid,uint64_t uid)55 void RSSurfaceBufferCallbackManager::UnregisterSurfaceBufferCallback(pid_t pid, uint64_t uid)
56 {
57 std::unique_lock<std::shared_mutex> lock { registerSurfaceBufferCallbackMutex_ };
58 auto iter = surfaceBufferCallbacks_.find({pid, uid});
59 if (iter == std::end(surfaceBufferCallbacks_)) {
60 RS_LOGE("RSSurfaceBufferCallbackManager::UnregisterSurfaceBufferCallback Pair:"
61 "[Pid: %{public}s, Uid: %{public}s] not exists.",
62 std::to_string(pid).c_str(), std::to_string(uid).c_str());
63 } else {
64 surfaceBufferCallbacks_.erase(iter);
65 }
66 }
67
GetSurfaceBufferOpItemCallback() const68 std::function<void(pid_t, uint64_t, uint32_t)> RSSurfaceBufferCallbackManager::GetSurfaceBufferOpItemCallback() const
69 {
70 auto mutablePtr = const_cast<RSSurfaceBufferCallbackManager*>(this);
71 return [mutablePtr](pid_t pid, uint64_t uid, uint32_t surfaceBufferId) {
72 mutablePtr->OnSurfaceBufferOpItemDestruct(pid, uid, surfaceBufferId);
73 };
74 }
75
GetSurfaceBufferCallback(pid_t pid,uint64_t uid) const76 sptr<RSISurfaceBufferCallback> RSSurfaceBufferCallbackManager::GetSurfaceBufferCallback(
77 pid_t pid, uint64_t uid) const
78 {
79 std::shared_lock<std::shared_mutex> lock { registerSurfaceBufferCallbackMutex_ };
80 auto iter = surfaceBufferCallbacks_.find({pid, uid});
81 if (iter == std::cend(surfaceBufferCallbacks_)) {
82 RS_LOGE("RSSurfaceBufferCallbackManager::GetSurfaceBufferCallback Pair:"
83 "[Pid: %{public}s, Uid: %{public}s] not exists.",
84 std::to_string(pid).c_str(), std::to_string(uid).c_str());
85 return nullptr;
86 }
87 return iter->second;
88 }
89
GetSurfaceBufferCallbackSize() const90 size_t RSSurfaceBufferCallbackManager::GetSurfaceBufferCallbackSize() const
91 {
92 std::shared_lock<std::shared_mutex> lock { registerSurfaceBufferCallbackMutex_ };
93 return surfaceBufferCallbacks_.size();
94 }
95
EnqueueSurfaceBufferId(pid_t pid,uint64_t uid,uint32_t surfaceBufferId)96 void RSSurfaceBufferCallbackManager::EnqueueSurfaceBufferId(pid_t pid, uint64_t uid, uint32_t surfaceBufferId)
97 {
98 auto iter = stagingSurfaceBufferIds_.find({pid, uid});
99 if (iter == std::end(stagingSurfaceBufferIds_)) {
100 std::tie(iter, std::ignore) = stagingSurfaceBufferIds_.insert({{pid, uid}, {}});
101 }
102 iter->second.push_back(surfaceBufferId);
103 }
104
OnSurfaceBufferOpItemDestruct(pid_t pid,uint64_t uid,uint32_t surfaceBufferId)105 void RSSurfaceBufferCallbackManager::OnSurfaceBufferOpItemDestruct(
106 pid_t pid, uint64_t uid, uint32_t surfaceBufferId)
107 {
108 std::lock_guard<std::mutex> lock { surfaceBufferOpItemMutex_ };
109 if (surfaceBufferCallbacks_.find({pid, uid}) == std::end(surfaceBufferCallbacks_)) {
110 RS_LOGE("RSSurfaceBufferCallbackManager::OnSurfaceBufferOpItemDestruct Pair:"
111 "[Pid: %{public}s, Uid: %{public}s] Callback not exists.",
112 std::to_string(pid).c_str(), std::to_string(uid).c_str());
113 return;
114 }
115 EnqueueSurfaceBufferId(pid, uid, surfaceBufferId);
116 }
117
RunSurfaceBufferCallback()118 void RSSurfaceBufferCallbackManager::RunSurfaceBufferCallback()
119 {
120 runPolicy_([this]() {
121 if (GetSurfaceBufferCallbackSize() == 0) {
122 return;
123 }
124 std::map<std::pair<pid_t, uint64_t>, std::vector<uint32_t>> surfaceBufferIds;
125 {
126 std::lock_guard<std::mutex> lock { surfaceBufferOpItemMutex_ };
127 surfaceBufferIds.swap(stagingSurfaceBufferIds_);
128 }
129 for (auto& [code, bufferIds] : surfaceBufferIds) {
130 auto [pid, uid] = code;
131 auto callback = GetSurfaceBufferCallback(pid, uid);
132 if (callback) {
133 callback->OnFinish(uid, bufferIds);
134 }
135 }
136 });
137 }
138 } // namespace Rosen
139 } // namespace OHOS
140