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 "aafwk_browser_host_impl.h"
17
18 #include "nweb_log.h"
19 #include "graphic_adapter.h"
20 #include "ibuffer_consumer_listener.h"
21 #include "iconsumer_surface.h"
22 #include "aafwk_browser_client_adapter_impl.h"
23 #include "aafwk_render_scheduler_impl.h"
24 #include "surface_utils.h"
25 #include "surface.h"
26 #include "ipc_types.h"
27 #include "foundation/graphic/graphic_surface/interfaces/inner_api/surface/window.h"
28 #include "foundation/graphic/graphic_surface/surface/include/native_window.h"
29
30 namespace OHOS::NWeb {
BrowserClient(const sptr<IRemoteObject> & impl)31 BrowserClient::BrowserClient(
32 const sptr<IRemoteObject> &impl) : IRemoteProxy<IBrowser>(impl) {}
33
WriteInterfaceToken(MessageParcel & data)34 bool BrowserClient::WriteInterfaceToken(MessageParcel &data)
35 {
36 if (!data.WriteInterfaceToken(BrowserClient::GetDescriptor())) {
37 return false;
38 }
39 return true;
40 }
41
QueryRenderSurface(int32_t surface_id)42 sptr<IRemoteObject> BrowserClient::QueryRenderSurface(int32_t surface_id)
43 {
44 MessageParcel data;
45 MessageParcel reply;
46 MessageOption option; // this should be a sync binder
47 if (!WriteInterfaceToken(data)) {
48 return nullptr;
49 }
50 data.WriteInt32(surface_id);
51 sptr<IRemoteObject> remote = Remote();
52 if (remote == nullptr) {
53 WVLOG_E("Remote is NULL.");
54 return nullptr;
55 }
56 int32_t ret = remote->SendRequest(
57 static_cast<uint32_t>(IBrowser::Message::QUERY_RENDER_SURFACE),
58 data, reply, option);
59 if (ret != NO_ERROR) {
60 WVLOG_E("SendRequest failed, error code = %{public}d", ret);
61 }
62 sptr<IRemoteObject> surface = reply.ReadRemoteObject();
63 return surface;
64 }
65
ReportThread(int32_t status,int32_t process_id,int32_t thread_id,int32_t role)66 void BrowserClient::ReportThread(int32_t status, int32_t process_id, int32_t thread_id, int32_t role)
67 {
68 MessageParcel data;
69 MessageParcel reply;
70 MessageOption option; // this should be a sync binder
71 if (!WriteInterfaceToken(data)) {
72 return;
73 }
74 data.WriteInt32(status);
75 data.WriteInt32(process_id);
76 data.WriteInt32(thread_id);
77 data.WriteInt32(role);
78 sptr<IRemoteObject> remote = Remote();
79 if (remote == nullptr) {
80 WVLOG_E("Remote is NULL.");
81 return;
82 }
83 int32_t ret = remote->SendRequest(
84 static_cast<uint32_t>(IBrowser::Message::REPORT_THREAD),
85 data, reply, option);
86 if (ret != NO_ERROR) {
87 WVLOG_E("SendRequest failed, error code = %{public}d", ret);
88 }
89 return;
90 }
91
PassSurface(sptr<Surface> surface,int64_t surface_id)92 void BrowserClient::PassSurface(sptr<Surface> surface, int64_t surface_id)
93 {
94 MessageParcel data;
95 MessageParcel reply;
96 MessageOption option; // this should be a sync binder
97 if (!WriteInterfaceToken(data)) {
98 return;
99 }
100 if (surface == nullptr) {
101 return;
102 }
103 data.WriteRemoteObject(surface->GetProducer()->AsObject());
104 data.WriteInt64(surface_id);
105 sptr<IRemoteObject> remote = Remote();
106 if (remote == nullptr) {
107 WVLOG_E("Remote is NULL.");
108 return;
109 }
110 int32_t ret = remote->SendRequest(
111 static_cast<uint32_t>(IBrowser::Message::PASS_SURFACE),
112 data, reply, option);
113 if (ret != NO_ERROR) {
114 WVLOG_E("SendRequest failed, error code = %{public}d", ret);
115 }
116 return;
117 }
118
DestroyRenderSurface(int32_t surface_id)119 void BrowserClient::DestroyRenderSurface(int32_t surface_id)
120 {
121 MessageParcel data;
122 MessageParcel reply;
123 MessageOption option; // this should be a sync binder
124 if (!WriteInterfaceToken(data)) {
125 return;
126 }
127 data.WriteInt32(surface_id);
128 sptr<IRemoteObject> remote = Remote();
129 if (remote == nullptr) {
130 WVLOG_E("Remote is NULL.");
131 return;
132 }
133 int32_t ret = remote->SendRequest(
134 static_cast<uint32_t>(IBrowser::Message::DESTROY_RENDER_SURFACE),
135 data, reply, option);
136 if (ret != NO_ERROR) {
137 WVLOG_E("SendRequest failed, error code = %{public}d", ret);
138 }
139 return;
140 }
141
AafwkBrowserClientAdapterImpl()142 AafwkBrowserClientAdapterImpl::AafwkBrowserClientAdapterImpl() {}
143
GetInstance()144 AafwkBrowserClientAdapterImpl& AafwkBrowserClientAdapterImpl::GetInstance()
145 {
146 static AafwkBrowserClientAdapterImpl instance;
147 return instance;
148 }
149
QueryRenderSurface(int32_t surface_id)150 void* AafwkBrowserClientAdapterImpl::QueryRenderSurface(int32_t surface_id)
151 {
152 std::unique_lock<std::mutex> window_map_lock(window_map_mutex_);
153 if (GetInstance().browserHost_) {
154 sptr<IRemoteObject> surfaceObject = GetInstance().browserHost_->QueryRenderSurface(surface_id);
155 // get return value
156 sptr<IBufferProducer> bufferProducer = iface_cast<IBufferProducer>(surfaceObject);
157 sptr<Surface> surface = Surface::CreateSurfaceAsProducer(bufferProducer);
158 OHNativeWindow* window = ::CreateNativeWindowFromSurface(&surface);
159 window_map_.emplace(surface_id, window);
160 void* newNativeWindow = reinterpret_cast<NWebNativeWindow>(window);
161 WVLOG_D("receive surface num = %{public}d", surface_id);
162 return newNativeWindow;
163 }
164 WVLOG_E("browserHost_ is not exist!");
165 return nullptr;
166 }
167
ReportThread(ResSchedStatusAdapter status,int32_t process_id,int32_t thread_id,ResSchedRoleAdapter role)168 void AafwkBrowserClientAdapterImpl::ReportThread(
169 ResSchedStatusAdapter status, int32_t process_id, int32_t thread_id, ResSchedRoleAdapter role)
170 {
171 int32_t resSchedStatus = static_cast<int>(status);
172 int32_t resSchedRole = static_cast<int>(role);
173 if (!GetInstance().browserHost_) {
174 WVLOG_E("browserHost_ is not exist!");
175 return;
176 }
177 GetInstance().browserHost_->ReportThread(resSchedStatus, process_id, thread_id, resSchedRole);
178 WVLOG_D("report thread id = %{public}d", thread_id);
179 return;
180 }
181
PassSurface(int64_t surface_id)182 void AafwkBrowserClientAdapterImpl::PassSurface(int64_t surface_id)
183 {
184 if (!GetInstance().browserHost_) {
185 WVLOG_E("browserHost_ is not exist!");
186 return;
187 }
188 SurfaceUtils* utils = SurfaceUtils::GetInstance();
189 if (!utils) {
190 WVLOG_E("get surfaceUtils failed!");
191 return;
192 }
193 sptr<Surface> surface = utils->GetSurface(surface_id);
194 if (!surface) {
195 WVLOG_E("get surface failed!");
196 return;
197 }
198 GetInstance().browserHost_->PassSurface(surface, surface_id);
199 return;
200 }
201
DestroyRenderSurface(int32_t surface_id)202 void AafwkBrowserClientAdapterImpl::DestroyRenderSurface(int32_t surface_id)
203 {
204 std::unique_lock<std::mutex> window_map_lock(window_map_mutex_);
205 if (!GetInstance().browserHost_) {
206 WVLOG_E("browserHost_ is not exist!");
207 return;
208 }
209
210 if (window_map_.find(surface_id) != window_map_.end()) {
211 OHNativeWindow* window = window_map_[surface_id];
212 ::DestoryNativeWindow(window);
213 window_map_.erase(surface_id);
214 }
215 GetInstance().browserHost_->DestroyRenderSurface(surface_id);
216 WVLOG_D("Destroy nweb surface id = %{public}d", surface_id);
217 }
218 } // namespace OHOS::NWeb