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