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 
24 namespace OHOS {
GetInstance()25 LiteWMS* LiteWMS::GetInstance()
26 {
27     static LiteWMS wms;
28     return &wms;
29 }
30 
WMSRequestHandle(int funcId,void * origin,IpcIo * req,IpcIo * reply)31 void 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 
SurfaceRequestHandler(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)82 int32_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 
GetSurface(IpcIo * req,IpcIo * reply)96 void 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 
Show(IpcIo * req,IpcIo * reply)122 void 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 
Hide(IpcIo * req,IpcIo * reply)130 void 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 
RaiseToTop(IpcIo * req,IpcIo * reply)138 void 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 
LowerToBottom(IpcIo * req,IpcIo * reply)146 void 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 
MoveTo(IpcIo * req,IpcIo * reply)154 void 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 
Resize(IpcIo * req,IpcIo * reply)166 void 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 
Update(IpcIo * req,IpcIo * reply)178 void 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 
CreateWindow(IpcIo * req,IpcIo * reply)186 void 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 
RemoveWindow(IpcIo * req,IpcIo * reply)201 void 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 
GetEventData(IpcIo * req,IpcIo * reply)209 void LiteWMS::GetEventData(IpcIo* req, IpcIo* reply)
210 {
211     DeviceData data;
212     LiteWM::GetInstance()->GetEventData(&data);
213     WriteRawData(reply, &data, sizeof(DeviceData));
214 }
215 
Screenshot(IpcIo * req,IpcIo * reply)216 void 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 
ClientRegister(IpcIo * req,IpcIo * reply)230 void 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 
DeathCallback(void * arg)248 void 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 
GetLayerInfo(IpcIo * req,IpcIo * reply)258 void 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