1 /*
2 * Copyright (c) 2022 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 "screenmanager_fuzzer.h"
17
18 #include <iostream>
19 #include <securec.h>
20
21 #include "dm_common.h"
22 #include "screen.h"
23 #include "screen_manager.h"
24
25 namespace OHOS::Rosen {
26 namespace {
27 constexpr size_t DATA_MIN_SIZE = 32;
28 }
29 class ScreenListener : public ScreenManager::IScreenListener {
30 public:
OnConnect(ScreenId screenId)31 virtual void OnConnect(ScreenId screenId) override
32 {
33 };
34
OnDisconnect(ScreenId screenId)35 virtual void OnDisconnect(ScreenId screenId) override
36 {
37 }
38
OnChange(ScreenId screenId)39 virtual void OnChange(ScreenId screenId) override
40 {
41 }
42 };
43
44 class ScreenGroupListener : public ScreenManager::IScreenGroupListener {
45 public:
OnChange(const std::vector<ScreenId> & screenIds,ScreenGroupChangeEvent event)46 virtual void OnChange(const std::vector<ScreenId>& screenIds, ScreenGroupChangeEvent event) override
47 {
48 }
49 };
50
51 class VirtualScreenGroupListener : public ScreenManager::IVirtualScreenGroupListener {
52 public:
OnMirrorChange(const ChangeInfo & info)53 void OnMirrorChange([[maybe_unused]]const ChangeInfo& info) override
54 {
55 }
56 };
57
58 template<class T>
GetObject(T & object,const uint8_t * data,size_t size)59 size_t GetObject(T &object, const uint8_t *data, size_t size)
60 {
61 size_t objectSize = sizeof(object);
62 if (objectSize > size) {
63 return 0;
64 }
65 return memcpy_s(&object, objectSize, data, objectSize) == EOK ? objectSize : 0;
66 }
67
ScreenPowerFuzzTest(const uint8_t * data,size_t size)68 bool ScreenPowerFuzzTest(const uint8_t *data, size_t size)
69 {
70 uint32_t screenPowerState;
71 uint32_t powerStateChangeReason;
72 if (data == nullptr || size < sizeof(screenPowerState) + sizeof(powerStateChangeReason)) {
73 return false;
74 }
75 size_t startPos = 0;
76 ScreenManager &screenManager = ScreenManager::GetInstance();
77 sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
78 screenManager.RegisterScreenListener(screenListener);
79 sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
80 screenManager.RegisterScreenGroupListener(screenGroupListener);
81
82 startPos += GetObject<uint32_t>(screenPowerState, data + startPos, size - startPos);
83 startPos += GetObject<uint32_t>(powerStateChangeReason, data + startPos, size - startPos);
84 screenManager.SetScreenPowerForAll(static_cast<ScreenPowerState>(screenPowerState),
85 static_cast<PowerStateChangeReason>(startPos));
86 std::vector<sptr<Screen>> allScreen;
87 screenManager.GetAllScreens(allScreen);
88 for (auto screen: allScreen) {
89 screenManager.GetScreenPower(screen->GetId());
90 }
91
92 screenManager.UnregisterScreenGroupListener(screenGroupListener);
93 screenManager.UnregisterScreenListener(screenListener);
94 return true;
95 }
96
MakeMirrorWithVirtualScreenFuzzTest(const uint8_t * data,size_t size)97 bool MakeMirrorWithVirtualScreenFuzzTest(const uint8_t *data, size_t size)
98 {
99 if (data == nullptr || size < DATA_MIN_SIZE) {
100 return false;
101 }
102 size_t startPos = 0;
103 ScreenManager &screenManager = ScreenManager::GetInstance();
104 sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
105 screenManager.RegisterScreenListener(screenListener);
106 sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
107 screenManager.RegisterScreenGroupListener(screenGroupListener);
108 screenManager.UnregisterScreenGroupListener(screenGroupListener);
109 screenManager.UnregisterScreenListener(screenListener);
110
111 std::string name = "screen";
112 VirtualScreenOption option = { name };
113 startPos += GetObject<uint32_t>(option.width_, data + startPos, size - startPos);
114 startPos += GetObject<uint32_t>(option.height_, data + startPos, size - startPos);
115 startPos += GetObject<float>(option.density_, data + startPos, size - startPos);
116 startPos += GetObject<int32_t>(option.flags_, data + startPos, size - startPos);
117 GetObject<bool>(option.isForShot_, data + startPos, size - startPos);
118 ScreenId screenId = screenManager.CreateVirtualScreen(option);
119
120 screenManager.SetVirtualScreenSurface(screenId, nullptr);
121
122 // make mirror
123 ScreenId groupId;
124 screenManager.MakeMirror(0, { screenId }, groupId);
125 if (groupId == SCREEN_ID_INVALID) {
126 screenManager.DestroyVirtualScreen(screenId);
127 }
128 sptr<ScreenGroup> group = screenManager.GetScreenGroup(groupId);
129 if (group == nullptr) {
130 screenManager.DestroyVirtualScreen(screenId);
131 return false;
132 }
133 std::vector<ScreenId> ids = group->GetChildIds();
134 screenManager.RemoveVirtualScreenFromGroup(ids);
135 return true;
136 }
137
MakeExpandWithVirtualScreenFuzzTest(const uint8_t * data,size_t size)138 bool MakeExpandWithVirtualScreenFuzzTest(const uint8_t *data, size_t size)
139 {
140 if (data == nullptr || size < sizeof(VirtualScreenOption)) {
141 return false;
142 }
143 size_t startPos = 0;
144 ScreenManager &screenManager = ScreenManager::GetInstance();
145 sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
146 screenManager.RegisterScreenListener(screenListener);
147 sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
148 screenManager.RegisterScreenGroupListener(screenGroupListener);
149 screenManager.UnregisterScreenGroupListener(screenGroupListener);
150 screenManager.UnregisterScreenListener(screenListener);
151
152 std::string name = "screen";
153 VirtualScreenOption option = { name };
154 startPos += GetObject<uint32_t>(option.width_, data + startPos, size - startPos);
155 startPos += GetObject<uint32_t>(option.height_, data + startPos, size - startPos);
156 startPos += GetObject<float>(option.density_, data + startPos, size - startPos);
157 startPos += GetObject<int32_t>(option.flags_, data + startPos, size - startPos);
158 GetObject<bool>(option.isForShot_, data + startPos, size - startPos);
159 ScreenId screenId = screenManager.CreateVirtualScreen(option);
160
161 screenManager.SetVirtualScreenSurface(screenId, nullptr);
162 // make expand
163 std::vector<ExpandOption> options = {{0, 0, 0}, {screenId, 0, 0}};
164 ScreenId groupId;
165 screenManager.MakeExpand(options, groupId);
166 if (groupId == SCREEN_ID_INVALID) {
167 screenManager.DestroyVirtualScreen(screenId);
168 }
169 sptr<ScreenGroup> group = screenManager.GetScreenGroup(groupId);
170 if (group == nullptr) {
171 screenManager.DestroyVirtualScreen(screenId);
172 return false;
173 }
174 std::vector<ScreenId> ids = group->GetChildIds();
175 screenManager.RemoveVirtualScreenFromGroup(ids);
176 return true;
177 }
178
CreateAndDestroyVirtualScreenFuzzTest(const uint8_t * data,size_t size)179 bool CreateAndDestroyVirtualScreenFuzzTest(const uint8_t *data, size_t size)
180 {
181 if (data == nullptr || size < sizeof(VirtualScreenOption)) {
182 return false;
183 }
184 size_t startPos = 0;
185 ScreenManager &screenManager = ScreenManager::GetInstance();
186 sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
187 screenManager.RegisterScreenListener(screenListener);
188 sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
189 screenManager.RegisterScreenGroupListener(screenGroupListener);
190
191 std::string name = "screen";
192 VirtualScreenOption option = { name };
193 startPos += GetObject<uint32_t>(option.width_, data + startPos, size - startPos);
194 startPos += GetObject<uint32_t>(option.height_, data + startPos, size - startPos);
195 startPos += GetObject<float>(option.density_, data + startPos, size - startPos);
196 startPos += GetObject<int32_t>(option.flags_, data + startPos, size - startPos);
197 startPos += GetObject<bool>(option.isForShot_, data + startPos, size - startPos);
198 ScreenId screenId = screenManager.CreateVirtualScreen(option);
199
200 screenManager.UnregisterScreenGroupListener(screenGroupListener);
201 screenManager.UnregisterScreenListener(screenListener);
202 screenManager.GetScreenById(screenId);
203 return true;
204 }
205
SetVirtualScreenSurfaceFuzzTest(const uint8_t * data,size_t size)206 bool SetVirtualScreenSurfaceFuzzTest(const uint8_t *data, size_t size)
207 {
208 ScreenId screenId;
209 if (data == nullptr || size < sizeof(screenId)) {
210 return false;
211 }
212 size_t startPos = 0;
213 ScreenManager &screenManager = ScreenManager::GetInstance();
214 GetObject<ScreenId>(screenId, data + startPos, size - startPos);
215 screenManager.SetVirtualScreenSurface(screenId, nullptr);
216 return true;
217 }
218
SetScreenRotationLockedFuzzTest(const uint8_t * data,size_t size)219 bool SetScreenRotationLockedFuzzTest(const uint8_t *data, size_t size)
220 {
221 ScreenId screenId;
222 if (data == nullptr || size < sizeof(screenId)) {
223 return false;
224 }
225 size_t startPos = 0;
226 ScreenManager &screenManager = ScreenManager::GetInstance();
227 bool flag = true;
228 startPos += GetObject<bool>(flag, data + startPos, size - startPos);
229 screenManager.SetScreenRotationLocked(flag);
230 return true;
231 }
232
IsScreenRotationLocked(const uint8_t * data,size_t size)233 bool IsScreenRotationLocked(const uint8_t *data, size_t size)
234 {
235 ScreenId screenId;
236 if (data == nullptr || size < sizeof(screenId)) {
237 return false;
238 }
239 size_t startPos = 0;
240 ScreenManager &screenManager = ScreenManager::GetInstance();
241 bool flag = true;
242 startPos += GetObject<bool>(flag, data + startPos, size - startPos);
243 screenManager.IsScreenRotationLocked(flag);
244 return true;
245 }
246
RemoveVirtualScreenFromGroupFuzzTest(const uint8_t * data,size_t size)247 bool RemoveVirtualScreenFromGroupFuzzTest(const uint8_t *data, size_t size)
248 {
249 ScreenId screenId;
250 if (data == nullptr || size < sizeof(screenId)) {
251 return false;
252 }
253 size_t startPos = 0;
254 ScreenManager &screenManager = ScreenManager::GetInstance();
255 GetObject<ScreenId>(screenId, data + startPos, size - startPos);
256 std::vector<ScreenId> screenIds = {screenId, screenId, screenId};
257 screenManager.RemoveVirtualScreenFromGroup(screenIds);
258 return true;
259 }
260
MakeMirrorFuzzTest(const uint8_t * data,size_t size)261 bool MakeMirrorFuzzTest(const uint8_t *data, size_t size)
262 {
263 ScreenId screenId;
264 // 10 screens.
265 if (data == nullptr || size < sizeof(ScreenId)) {
266 return false;
267 }
268 size_t startPos = 0;
269 ScreenManager &screenManager = ScreenManager::GetInstance();
270 sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
271 screenManager.RegisterScreenListener(screenListener);
272 sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
273 screenManager.RegisterScreenGroupListener(screenGroupListener);
274
275 std::vector<ScreenId> screenIds;
276 // 10 screens
277 for (size_t i = 0; i < 10; i++) {
278 startPos += GetObject<ScreenId>(screenId, data + startPos, size - startPos);
279 screenIds.emplace_back(screenId);
280 }
281 ScreenId screenGroupId;
282 GetObject<ScreenId>(screenId, data + startPos, size - startPos);
283 screenManager.MakeMirror(screenId, screenIds, screenGroupId);
284 screenManager.UnregisterScreenGroupListener(screenGroupListener);
285 screenManager.UnregisterScreenListener(screenListener);
286 return true;
287 }
288
MakeExpandFuzzTest(const uint8_t * data,size_t size)289 bool MakeExpandFuzzTest(const uint8_t *data, size_t size)
290 {
291 ScreenId screenId;
292 // 10 screens.
293 if (data == nullptr || size < sizeof(ScreenId)) {
294 return false;
295 }
296 size_t startPos = 0;
297 ScreenManager &screenManager = ScreenManager::GetInstance();
298 sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
299 startPos += GetObject<ScreenId>(screenId, data + startPos, size - startPos);
300 screenListener->OnConnect(screenId);
301 screenListener->OnDisconnect(screenId);
302 screenListener->OnChange(screenId);
303 screenManager.RegisterScreenListener(screenListener);
304 sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
305 screenManager.RegisterScreenGroupListener(screenGroupListener);
306 std::vector<ExpandOption> options;
307 // 10 screens
308 for (size_t i = 0; i < 10; i++) {
309 startPos += GetObject<ScreenId>(screenId, data + startPos, size - startPos);
310 ExpandOption option = {screenId, 0, 0};
311 options.emplace_back(option);
312 }
313 ScreenId screenGroupId;
314 screenManager.MakeExpand(options, screenGroupId);
315 screenManager.UnregisterScreenGroupListener(screenGroupListener);
316 screenManager.UnregisterScreenListener(screenListener);
317 sptr<ScreenManager::IVirtualScreenGroupListener> virtualScreenGroupListener = new VirtualScreenGroupListener();
318 screenManager.RegisterVirtualScreenGroupListener(virtualScreenGroupListener);
319 screenManager.UnregisterVirtualScreenGroupListener(virtualScreenGroupListener);
320 return true;
321 }
322 } // namespace.OHOS::Rosen
323
324 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)325 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
326 {
327 /* Run your code on data */
328 OHOS::Rosen::ScreenPowerFuzzTest(data, size);
329 OHOS::Rosen::MakeMirrorWithVirtualScreenFuzzTest(data, size);
330 OHOS::Rosen::MakeMirrorFuzzTest(data, size);
331 OHOS::Rosen::MakeExpandWithVirtualScreenFuzzTest(data, size);
332 OHOS::Rosen::MakeExpandFuzzTest(data, size);
333 OHOS::Rosen::CreateAndDestroyVirtualScreenFuzzTest(data, size);
334 OHOS::Rosen::SetVirtualScreenSurfaceFuzzTest(data, size);
335 OHOS::Rosen::RemoveVirtualScreenFromGroupFuzzTest(data, size);
336 OHOS::Rosen::SetScreenRotationLockedFuzzTest(data, size);
337 OHOS::Rosen::IsScreenRotationLocked(data, size);
338 return 0;
339 }
340
341