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:
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 < DATA_MIN_SIZE) {
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 < DATA_MIN_SIZE) {
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 screenManager.DestroyVirtualScreen(screenId);
204 return true;
205 }
206
SetVirtualScreenSurfaceFuzzTest(const uint8_t * data,size_t size)207 bool SetVirtualScreenSurfaceFuzzTest(const uint8_t *data, size_t size)
208 {
209 ScreenId screenId;
210 if (data == nullptr || size < sizeof(screenId)) {
211 return false;
212 }
213 size_t startPos = 0;
214 ScreenManager &screenManager = ScreenManager::GetInstance();
215 GetObject<ScreenId>(screenId, data + startPos, size - startPos);
216 screenManager.SetVirtualScreenSurface(screenId, nullptr);
217 return true;
218 }
219
SetScreenRotationLockedFuzzTest(const uint8_t * data,size_t size)220 bool SetScreenRotationLockedFuzzTest(const uint8_t *data, size_t size)
221 {
222 ScreenId screenId;
223 if (data == nullptr || size < sizeof(screenId)) {
224 return false;
225 }
226 size_t startPos = 0;
227 ScreenManager &screenManager = ScreenManager::GetInstance();
228 bool flag = true;
229 startPos += GetObject<bool>(flag, data + startPos, size - startPos);
230 screenManager.SetScreenRotationLocked(flag);
231 return true;
232 }
233
IsScreenRotationLocked(const uint8_t * data,size_t size)234 bool IsScreenRotationLocked(const uint8_t *data, size_t size)
235 {
236 ScreenId screenId;
237 if (data == nullptr || size < sizeof(screenId)) {
238 return false;
239 }
240 size_t startPos = 0;
241 ScreenManager &screenManager = ScreenManager::GetInstance();
242 bool flag = true;
243 startPos += GetObject<bool>(flag, data + startPos, size - startPos);
244 screenManager.IsScreenRotationLocked(flag);
245 return true;
246 }
247
RemoveVirtualScreenFromGroupFuzzTest(const uint8_t * data,size_t size)248 bool RemoveVirtualScreenFromGroupFuzzTest(const uint8_t *data, size_t size)
249 {
250 ScreenId screenId;
251 if (data == nullptr || size < sizeof(screenId)) {
252 return false;
253 }
254 size_t startPos = 0;
255 ScreenManager &screenManager = ScreenManager::GetInstance();
256 GetObject<ScreenId>(screenId, data + startPos, size - startPos);
257 std::vector<ScreenId> screenIds = {screenId, screenId, screenId};
258 screenManager.RemoveVirtualScreenFromGroup(screenIds);
259 return true;
260 }
261
MakeMirrorFuzzTest(const uint8_t * data,size_t size)262 bool MakeMirrorFuzzTest(const uint8_t *data, size_t size)
263 {
264 ScreenId screenId;
265 // 10 screens.
266 if (data == nullptr || size < sizeof(ScreenId)) {
267 return false;
268 }
269 size_t startPos = 0;
270 ScreenManager &screenManager = ScreenManager::GetInstance();
271 sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
272 screenManager.RegisterScreenListener(screenListener);
273 sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
274 screenManager.RegisterScreenGroupListener(screenGroupListener);
275
276 std::vector<ScreenId> screenIds;
277 // 10 screens
278 for (size_t i = 0; i < 10; i++) {
279 startPos += GetObject<ScreenId>(screenId, data + startPos, size - startPos);
280 screenIds.emplace_back(screenId);
281 }
282 ScreenId screenGroupId;
283 GetObject<ScreenId>(screenId, data + startPos, size - startPos);
284 screenManager.MakeMirror(screenId, screenIds, screenGroupId);
285 screenManager.UnregisterScreenGroupListener(screenGroupListener);
286 screenManager.UnregisterScreenListener(screenListener);
287 return true;
288 }
289
MakeExpandFuzzTest(const uint8_t * data,size_t size)290 bool MakeExpandFuzzTest(const uint8_t *data, size_t size)
291 {
292 ScreenId screenId;
293 // 10 screens.
294 if (data == nullptr || size < sizeof(ScreenId)) {
295 return false;
296 }
297 size_t startPos = 0;
298 ScreenManager &screenManager = ScreenManager::GetInstance();
299 sptr<ScreenManager::IScreenListener> screenListener = new ScreenListener();
300 startPos += GetObject<ScreenId>(screenId, data + startPos, size - startPos);
301 screenListener->OnConnect(screenId);
302 screenListener->OnDisconnect(screenId);
303 screenListener->OnChange(screenId);
304 screenManager.RegisterScreenListener(screenListener);
305 sptr<ScreenManager::IScreenGroupListener> screenGroupListener = new ScreenGroupListener();
306 screenManager.RegisterScreenGroupListener(screenGroupListener);
307 std::vector<ExpandOption> options;
308 // 10 screens
309 for (size_t i = 0; i < 10; i++) {
310 startPos += GetObject<ScreenId>(screenId, data + startPos, size - startPos);
311 ExpandOption option = {screenId, 0, 0};
312 options.emplace_back(option);
313 }
314 ScreenId screenGroupId;
315 screenManager.MakeExpand(options, screenGroupId);
316 screenManager.UnregisterScreenGroupListener(screenGroupListener);
317 screenManager.UnregisterScreenListener(screenListener);
318 sptr<ScreenManager::IVirtualScreenGroupListener> virtualScreenGroupListener = new VirtualScreenGroupListener();
319 screenManager.RegisterVirtualScreenGroupListener(virtualScreenGroupListener);
320 screenManager.UnregisterVirtualScreenGroupListener(virtualScreenGroupListener);
321 return true;
322 }
323 } // namespace.OHOS::Rosen
324
325 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)326 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
327 {
328 /* Run your code on data */
329 OHOS::Rosen::ScreenPowerFuzzTest(data, size);
330 OHOS::Rosen::MakeMirrorWithVirtualScreenFuzzTest(data, size);
331 OHOS::Rosen::MakeMirrorFuzzTest(data, size);
332 OHOS::Rosen::MakeExpandWithVirtualScreenFuzzTest(data, size);
333 OHOS::Rosen::MakeExpandFuzzTest(data, size);
334 OHOS::Rosen::CreateAndDestroyVirtualScreenFuzzTest(data, size);
335 OHOS::Rosen::SetVirtualScreenSurfaceFuzzTest(data, size);
336 OHOS::Rosen::RemoveVirtualScreenFromGroupFuzzTest(data, size);
337 OHOS::Rosen::SetScreenRotationLockedFuzzTest(data, size);
338 OHOS::Rosen::IsScreenRotationLocked(data, size);
339 return 0;
340 }
341
342