1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "Common.h"
18 #include "DefaultEngine.h"
19 #include "VideoInputManager.h"
20
21 #include <android-base/file.h>
22 #include <fuzzer/FuzzedDataProvider.h>
23 #include <gmock/gmock.h>
24
25 #include <stdio.h>
26 #include <unistd.h>
27
28 namespace android {
29 namespace automotive {
30 namespace computepipe {
31 namespace runner {
32 namespace input_manager {
33
34 using android::base::Dirname;
35
36 namespace {
37
38 class MockRunnerEvent : public RunnerEvent {
39 public:
40 MOCK_CONST_METHOD0(isPhaseEntry, bool());
41 MOCK_CONST_METHOD0(isTransitionComplete, bool());
42 MOCK_CONST_METHOD0(isAborted, bool());
43 MOCK_METHOD1(dispatchToComponent,
44 Status(const std::shared_ptr<RunnerComponentInterface>& iface));
45 };
46
47 enum INPUT_MGR_FUZZ_FUNCS { RUNNER_COMP_BASE_ENUM };
48
49 static std::shared_ptr<VideoInputManager> manager;
50
LLVMFuzzerInitialize(int * argc,char *** argv)51 extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
52 const std::string kFilename =
53 Dirname(*argv[0]) + "/data/corpus/video_input_manager/centaur_1.mpg";
54 if (access(kFilename.c_str(), F_OK) == -1) {
55 std::cerr << "Video file does not exist!" << std::endl;
56 exit(1);
57 }
58
59 // Initialize input config
60 proto::InputConfig inputConf;
61 proto::InputStreamConfig* streamConfig = inputConf.add_input_stream();
62 proto::VideoFileConfig* videoConfig = streamConfig->mutable_video_config();
63 videoConfig->set_file_path(kFilename);
64
65 // Initialize callBack, which does nothing
66 std::shared_ptr<InputEngineInterface> callBack = std::make_shared<engine::InputCallback>(
67 0, [](int i) {},
68 [](int i, int64_t j, const InputFrame& frame) { return Status::SUCCESS; });
69
70 // Initialize manager
71 manager = std::make_shared<VideoInputManager>(inputConf, inputConf /* redundant */, callBack);
72 return 0;
73 }
74
75 // TODO(b/163138279, b/163138595) verify the fix for these two bugs
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)76 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
77 FuzzedDataProvider fdp(data, size);
78 while (fdp.remaining_bytes() > test::kMaxFuzzerConsumedBytes) {
79 switch (fdp.ConsumeIntegralInRange<uint32_t>(0, API_SUM - 1)) {
80 case HANDLE_CONFIG_PHASE: {
81 break;
82 }
83 case HANDLE_EXECUTION_PHASE: {
84 testing::NiceMock<MockRunnerEvent> e;
85 bool isTransitionComplete = fdp.ConsumeBool();
86 bool isPhaseEntry = fdp.ConsumeBool();
87 if (isTransitionComplete != isPhaseEntry) {
88 if (isTransitionComplete) {
89 EXPECT_CALL((e), isTransitionComplete()).WillOnce([isTransitionComplete]() {
90 return isTransitionComplete;
91 });
92 ON_CALL((e), isPhaseEntry()).WillByDefault([isPhaseEntry]() {
93 return isPhaseEntry;
94 });
95 } else if (isPhaseEntry) {
96 ON_CALL((e), isTransitionComplete())
97 .WillByDefault(
98 [isTransitionComplete]() { return isTransitionComplete; });
99 EXPECT_CALL((e), isPhaseEntry()).WillOnce([isPhaseEntry]() {
100 return isPhaseEntry;
101 });
102 }
103 Status res = manager->handleExecutionPhase(e);
104 if (res == Status::SUCCESS && !isTransitionComplete && isPhaseEntry) {
105 sleep(3); // waiting for resource to be released
106 } else {
107 usleep(10);
108 }
109 }
110 break;
111 }
112 case HANDLE_STOP_IMMEDIATE_PHASE: {
113 testing::NiceMock<MockRunnerEvent> e;
114 manager->handleStopImmediatePhase(e);
115 break;
116 }
117 case HANDLE_STOP_WITH_FLUSH_PHASE: {
118 testing::NiceMock<MockRunnerEvent> e;
119 manager->handleStopWithFlushPhase(e);
120 break;
121 }
122 case HANDLE_RESET_PHASE: {
123 testing::NiceMock<MockRunnerEvent> e;
124 manager->handleResetPhase(e);
125 break;
126 }
127 default:
128 LOG(ERROR) << "Unexpected option aborting...";
129 break;
130 }
131 }
132 return 0;
133 }
134
135 } // namespace
136 } // namespace input_manager
137 } // namespace runner
138 } // namespace computepipe
139 } // namespace automotive
140 } // namespace android
141