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_wms.h"
17#include "gfx_utils/graphic_log.h"
18#include "lite_wm.h"
19#include "lite_wm_type.h"
20#include "pms_interface.h"
21#include "surface.h"
22#include "surface_impl.h"
23
24namespace OHOS {
25LiteWMS* LiteWMS::GetInstance()
26{
27    static LiteWMS wms;
28    return &wms;
29}
30
31void LiteWMS::WMSRequestHandle(int funcId, void* origin, IpcIo* req, IpcIo* reply)
32{
33    switch (funcId) {
34        case LiteWMS_GetSurface:
35            OHOS::LiteWMS::GetInstance()->GetSurface(req, reply);
36            break;
37        case LiteWMS_Show:
38            LiteWMS::GetInstance()->Show(req, reply);
39            break;
40        case LiteWMS_Hide:
41            LiteWMS::GetInstance()->Hide(req, reply);
42            break;
43        case LiteWMS_RaiseToTop:
44            LiteWMS::GetInstance()->RaiseToTop(req, reply);
45            break;
46        case LiteWMS_LowerToBottom:
47            LiteWMS::GetInstance()->LowerToBottom(req, reply);
48            break;
49        case LiteWMS_MoveTo:
50            LiteWMS::GetInstance()->MoveTo(req, reply);
51            break;
52        case LiteWMS_Resize:
53            LiteWMS::GetInstance()->Resize(req, reply);
54            break;
55        case LiteWMS_Update:
56            LiteWMS::GetInstance()->Update(req, reply);
57            break;
58        case LiteWMS_CreateWindow:
59            LiteWMS::GetInstance()->CreateWindow(req, reply);
60            break;
61        case LiteWMS_RemoveWindow:
62            LiteWMS::GetInstance()->RemoveWindow(req, reply);
63            break;
64        case LiteWMS_GetEventData:
65            LiteWMS::GetInstance()->GetEventData(req, reply);
66            break;
67        case LiteWMS_Screenshot:
68            LiteWMS::GetInstance()->Screenshot(req, reply);
69            break;
70        case LiteWMS_ClientRegister:
71            LiteWMS::GetInstance()->ClientRegister(req, reply);
72            break;
73        case LiteWMS_GetLayerInfo:
74            LiteWMS::GetInstance()->GetLayerInfo(req, reply);
75            break;
76        default:
77            GRAPHIC_LOGW("code not support:%d!", funcId);
78            break;
79    }
80}
81
82int32_t LiteWMS::SurfaceRequestHandler(uint32_t code, IpcIo* data, IpcIo* reply, MessageOption option)
83{
84    LiteWindow* window = reinterpret_cast<LiteWindow*>(option.args);
85    if (code == 0) {
86        GRAPHIC_LOGI("requestBuffer");
87        window->UpdateBackBuf();
88    }
89
90    Surface* surface = window->GetSurface();
91    SurfaceImpl* liteSurface = reinterpret_cast<SurfaceImpl*>(surface);
92    liteSurface->DoIpcMsg(code, data, reply, option);
93    return 0;
94}
95
96void LiteWMS::GetSurface(IpcIo* req, IpcIo* reply)
97{
98    int32_t id;
99    ReadInt32(req, &id);
100    GRAPHIC_LOGI("GetSurface,id=%d", id);
101    LiteWindow* window = LiteWM::GetInstance()->GetWindowById(id);
102    if (window == nullptr) {
103        GRAPHIC_LOGE("window not found, id = %d", id);
104        return;
105    }
106    IpcObjectStub* objectStub = new IpcObjectStub();
107    if (objectStub == nullptr) {
108        return;
109    }
110    SvcIdentity svc;
111    objectStub->func = SurfaceRequestHandler;
112    objectStub->args = window;
113    objectStub->isRemote = false;
114    svc.handle = IPC_INVALID_HANDLE;
115    svc.token = SERVICE_TYPE_ANONYMOUS;
116    svc.cookie = reinterpret_cast<uintptr_t>(objectStub);
117    WriteInt32(reply, 0);
118    window->SetSid(svc);
119    WriteRemoteObject(reply, &svc);
120}
121
122void LiteWMS::Show(IpcIo* req, IpcIo* reply)
123{
124    GRAPHIC_LOGI("Show");
125    int32_t id;
126    ReadInt32(req, &id);
127    LiteWM::GetInstance()->Show(id);
128}
129
130void LiteWMS::Hide(IpcIo* req, IpcIo* reply)
131{
132    GRAPHIC_LOGI("Hide");
133    int32_t id;
134    ReadInt32(req, &id);
135    LiteWM::GetInstance()->Hide(id);
136}
137
138void LiteWMS::RaiseToTop(IpcIo* req, IpcIo* reply)
139{
140    GRAPHIC_LOGI("RaiseToTop");
141    int32_t id;
142    ReadInt32(req, &id);
143    LiteWM::GetInstance()->RaiseToTop(id);
144}
145
146void LiteWMS::LowerToBottom(IpcIo* req, IpcIo* reply)
147{
148    GRAPHIC_LOGI("LowerToBottom");
149    int32_t id;
150    ReadInt32(req, &id);
151    LiteWM::GetInstance()->LowerToBottom(id);
152}
153
154void LiteWMS::MoveTo(IpcIo* req, IpcIo* reply)
155{
156    GRAPHIC_LOGI("MoveTo");
157    int32_t id;
158    ReadInt32(req, &id);
159    uint32_t x;
160    ReadUint32(req, &x);
161    uint32_t y;
162    ReadUint32(req, &y);
163    LiteWM::GetInstance()->MoveTo(id, x, y);
164}
165
166void LiteWMS::Resize(IpcIo* req, IpcIo* reply)
167{
168    GRAPHIC_LOGI("Resize");
169    int32_t id;
170    ReadInt32(req, &id);
171    uint32_t width;
172    ReadUint32(req, &width);
173    uint32_t height;
174    ReadUint32(req, &height);
175    LiteWM::GetInstance()->Resize(id, width, height);
176}
177
178void LiteWMS::Update(IpcIo* req, IpcIo* reply)
179{
180    GRAPHIC_LOGI("Update");
181    int32_t id;
182    ReadInt32(req, &id);
183    LiteWM::GetInstance()->UpdateWindow(id);
184}
185
186void LiteWMS::CreateWindow(IpcIo* req, IpcIo* reply)
187{
188    GRAPHIC_LOGI("CreateWindow");
189    LiteWinConfig* config = static_cast<LiteWinConfig*>(ReadRawData(req, sizeof(LiteWinConfig)));
190    if (config != nullptr) {
191        pid_t pid = GetCallingPid();
192        LiteWindow* window = LiteWM::GetInstance()->CreateWindow(*config, pid);
193        if (window != nullptr) {
194            WriteInt32(reply, window->GetWindowId());
195            return;
196        }
197    }
198    WriteInt32(reply, INVALID_WINDOW_ID);
199}
200
201void LiteWMS::RemoveWindow(IpcIo* req, IpcIo* reply)
202{
203    GRAPHIC_LOGI("RemoveWindow");
204    int32_t id;
205    ReadInt32(req, &id);
206    LiteWM::GetInstance()->RemoveWindow(id);
207}
208
209void LiteWMS::GetEventData(IpcIo* req, IpcIo* reply)
210{
211    DeviceData data;
212    LiteWM::GetInstance()->GetEventData(&data);
213    WriteRawData(reply, &data, sizeof(DeviceData));
214}
215
216void LiteWMS::Screenshot(IpcIo* req, IpcIo* reply)
217{
218    const char *writeMediaImagePermissionName = "ohos.permission.WRITE_MEDIA_IMAGES";
219    pid_t uid = GetCallingUid();
220    if (CheckPermission(uid, writeMediaImagePermissionName) != GRANTED) {
221        GRAPHIC_LOGE("permission denied");
222        WriteInt32(reply, LiteWMS_EUNKNOWN);
223        return;
224    }
225    Surface* surface = SurfaceImpl::GenericSurfaceByIpcIo(*req);
226    bool ret = LiteWM::GetInstance()->OnScreenshot(surface);
227    WriteInt32(reply, ret ? LiteWMS_EOK : LiteWMS_EUNKNOWN);
228}
229
230void LiteWMS::ClientRegister(IpcIo* req, IpcIo* reply)
231{
232    pid_t pid = GetCallingPid();
233    SvcIdentity sid;
234    bool ret = ReadRemoteObject(req, &sid);
235    if (!ret) {
236        return;
237    }
238
239    DeathCallbackArg* arg = new DeathCallbackArg;
240    arg->pid = pid;
241    arg->sid = sid;
242    uint32_t cbId = -1;
243    if (AddDeathRecipient(arg->sid, DeathCallback, arg, &cbId) != 0) {
244        GRAPHIC_LOGE("AddDeathRecipient failed!");
245    }
246}
247
248void LiteWMS::DeathCallback(void* arg)
249{
250    if (arg != nullptr) {
251        DeathCallbackArg* cbArg = static_cast<DeathCallbackArg*>(arg);
252        LiteWM::GetInstance()->OnClientDeathNotify(cbArg->pid);
253        ReleaseSvc(cbArg->sid);
254        delete cbArg;
255    }
256}
257
258void LiteWMS::GetLayerInfo(IpcIo* req, IpcIo* reply)
259{
260    LiteLayerInfo layerInfo = {};
261    LiteWM::GetInstance()->GetLayerInfo(layerInfo);
262    WriteRawData(reply, &layerInfo, sizeof(LiteLayerInfo));
263}
264} // namespace OHOS
265