1 /*
2 * Copyright (c) 2020-2021 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 "lite_wm_requestor.h"
17 #include "gfx_utils/graphic_log.h"
18 #include "gfx_utils/input_event_info.h"
19 #include "gfx_utils/pixel_format_utils.h"
20 #include "lite_wms_client.h"
21 #include "surface_impl.h"
22
23 namespace OHOS {
24 static IpcObjectStub objectStub;
GetInstance()25 LiteWMRequestor* LiteWMRequestor::GetInstance()
26 {
27 static LiteWMRequestor requestor;
28 return &requestor;
29 }
30
LiteWMRequestor()31 LiteWMRequestor::LiteWMRequestor() : proxy_(nullptr), listener_(nullptr), surface_(nullptr), sid_({}), layerInfo_({})
32 {
33 proxy_ = LiteWMSClient::GetInstance()->GetClientProxy();
34 }
35
Callback(void * owner,int code,IpcIo * reply)36 int LiteWMRequestor::Callback(void* owner, int code, IpcIo* reply)
37 {
38 if ((code != 0) || (owner == nullptr)) {
39 return -1;
40 }
41
42 CallBackPara* para = static_cast<CallBackPara*>(owner);
43 switch (para->funcId) {
44 case LiteWMS_CreateWindow: {
45 LiteWinRequestor** requestor = static_cast<LiteWinRequestor**>(para->data);
46 if (requestor == nullptr) {
47 break;
48 }
49 int32_t id;
50 ReadInt32(reply, &id);
51 GRAPHIC_LOGI("CreateWindow, id=%d", id);
52 if (id == INVALID_WINDOW_ID) {
53 *requestor = nullptr;
54 } else {
55 *requestor = new LiteWinRequestor(id);
56 }
57 break;
58 }
59 case LiteWMS_GetEventData: {
60 DeviceData* data = static_cast<DeviceData*>(ReadRawData(reply, sizeof(DeviceData)));
61 DeviceData* retData = static_cast<DeviceData*>(para->data);
62 if (data != nullptr && retData != nullptr) {
63 *retData = *data;
64 }
65 break;
66 }
67 case LiteWMS_Screenshot: {
68 int32_t ret;
69 ReadInt32(reply, &ret);
70 if (ret != LiteWMS_EOK) {
71 GRAPHIC_LOGW("Screenshot busy!");
72 LiteWMRequestor::GetInstance()->ScreenShotClearup();
73 }
74 break;
75 }
76 case LiteWMS_GetLayerInfo: {
77 LiteLayerInfo* data = static_cast<LiteLayerInfo*>(ReadRawData(reply, sizeof(LiteLayerInfo)));
78 LiteLayerInfo* retData = static_cast<LiteLayerInfo*>(para->data);
79 if (data != nullptr && retData != nullptr) {
80 *retData = *data;
81 }
82 break;
83 }
84 default:
85 break;
86 }
87 return 0;
88 }
89
WmsMsgHandler(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)90 int32_t LiteWMRequestor::WmsMsgHandler(uint32_t code, IpcIo* data, IpcIo* reply, MessageOption option)
91 {
92 // It's not used yet
93 return 0;
94 }
95
ClientRegister()96 void LiteWMRequestor::ClientRegister()
97 {
98 IpcIo io;
99 uint8_t tmpData[DEFAULT_IPC_SIZE];
100 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1);
101
102 SvcIdentity svc;
103 objectStub.func = WmsMsgHandler;
104 objectStub.args = nullptr;
105 objectStub.isRemote = false;
106 svc.handle = IPC_INVALID_HANDLE;
107 svc.token = SERVICE_TYPE_ANONYMOUS;
108 svc.cookie = reinterpret_cast<uintptr_t>(&objectStub);
109 WriteRemoteObject(&io, &svc);
110 int32_t ret = proxy_->Invoke(proxy_, LiteWMS_ClientRegister, &io, NULL, Callback);
111 if (ret != 0) {
112 GRAPHIC_LOGE("ClientRegister failed, ret=%d", ret);
113 }
114 }
115
GetLayerInfo()116 void LiteWMRequestor::GetLayerInfo()
117 {
118 IpcIo io;
119 uint8_t tmpData[DEFAULT_IPC_SIZE];
120 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
121
122 CallBackPara para = {};
123 para.funcId = LiteWMS_GetLayerInfo;
124 para.data = &layerInfo_;
125 int32_t ret = proxy_->Invoke(proxy_, LiteWMS_GetLayerInfo, &io, ¶, Callback);
126 if (ret != 0) {
127 GRAPHIC_LOGE("GetLayerInfo failed, ret=%d", ret);
128 }
129 }
130
CreateWindow(const LiteWinConfig & config)131 LiteWinRequestor* LiteWMRequestor::CreateWindow(const LiteWinConfig& config)
132 {
133 IpcIo io;
134 uint8_t tmpData[DEFAULT_IPC_SIZE];
135 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
136 WriteRawData(&io, &config, sizeof(LiteWinConfig));
137
138 LiteWinRequestor* requestor = nullptr;
139 CallBackPara para = {};
140 para.funcId = LiteWMS_CreateWindow;
141 para.data = &requestor;
142 int32_t ret = proxy_->Invoke(proxy_, LiteWMS_CreateWindow, &io, ¶, Callback);
143 if (ret != 0) {
144 GRAPHIC_LOGE("CreateWindow failed, ret=%d", ret);
145 }
146
147 return requestor;
148 }
149
RemoveWindow(int32_t id)150 void LiteWMRequestor::RemoveWindow(int32_t id)
151 {
152 IpcIo io;
153 uint8_t tmpData[DEFAULT_IPC_SIZE];
154 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
155 WriteInt32(&io, id);
156
157 int32_t ret = proxy_->Invoke(proxy_, LiteWMS_RemoveWindow, &io, NULL, Callback);
158 if (ret != 0) {
159 GRAPHIC_LOGE("RemoveWindow failed, ret=%d", ret);
160 }
161 }
162
GetEventData(DeviceData * data)163 void LiteWMRequestor::GetEventData(DeviceData* data)
164 {
165 IpcIo io;
166 uint8_t tmpData[DEFAULT_IPC_SIZE];
167 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
168
169 CallBackPara para = {};
170 para.funcId = LiteWMS_GetEventData;
171 para.data = data;
172 (void)proxy_->Invoke(proxy_, LiteWMS_GetEventData, &io, ¶, Callback);
173 }
174
SurfaceRequestHandler(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)175 int LiteWMRequestor::SurfaceRequestHandler(uint32_t code, IpcIo* data, IpcIo* reply, MessageOption option)
176 {
177 SurfaceImpl* surface = reinterpret_cast<SurfaceImpl*>(option.args);
178 if (surface == nullptr) {
179 return 0;
180 }
181 surface->DoIpcMsg(code, data, reply, option);
182 return 0;
183 }
184
ScreenShotClearup()185 void LiteWMRequestor::ScreenShotClearup()
186 {
187 if (surface_ != nullptr) {
188 delete surface_;
189 surface_ = nullptr;
190 }
191 }
192
OnBufferAvailable()193 void LiteWMRequestor::OnBufferAvailable()
194 {
195 GRAPHIC_LOGD("OnBufferAvailable");
196 if (surface_ != nullptr) {
197 SurfaceBuffer* buffer = surface_->AcquireBuffer();
198 if (buffer != nullptr) {
199 if (listener_ != nullptr) {
200 uint8_t* virAddr = static_cast<uint8_t*>(buffer->GetVirAddr());
201 uint32_t width = surface_->GetWidth();
202 uint32_t height = surface_->GetHeight();
203 ImagePixelFormat format = static_cast<ImagePixelFormat>(surface_->GetFormat());
204 uint32_t stride = surface_->GetStride();
205 listener_->OnScreenshotEnd(virAddr, width, height, format, stride);
206 }
207 surface_->ReleaseBuffer(buffer);
208 }
209 ScreenShotClearup();
210 }
211 }
212
Screenshot()213 void LiteWMRequestor::Screenshot()
214 {
215 if (surface_ != nullptr || listener_ == nullptr) {
216 return;
217 }
218
219 surface_ = Surface::CreateSurface();
220 if (surface_ == nullptr) {
221 return;
222 }
223
224 surface_->SetWidthAndHeight(layerInfo_.width, layerInfo_.height);
225 surface_->SetFormat(layerInfo_.pixelFormat);
226 surface_->SetUsage(1);
227 surface_->RegisterConsumerListener(*this);
228
229 objectStub_ .func = SurfaceRequestHandler;
230 objectStub_ .args = surface_;
231 objectStub_ .isRemote = false;
232 sid_.handle = IPC_INVALID_HANDLE;
233 sid_.token = SERVICE_TYPE_ANONYMOUS;
234 sid_.cookie = reinterpret_cast<uintptr_t>(&objectStub_);
235
236 IpcIo io;
237 uint8_t tmpData[DEFAULT_IPC_SIZE];
238 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1);
239 WriteRemoteObject(&io, &sid_);
240 CallBackPara para = {};
241 para.funcId = LiteWMS_Screenshot;
242 int32_t ret = proxy_->Invoke(proxy_, LiteWMS_Screenshot, &io, ¶, Callback);
243 if (ret != 0) {
244 GRAPHIC_LOGE("Screenshot failed, ret=%d", ret);
245 }
246 }
247 } // namespace OHOS
248