Add PixelStreamMangerFuzzer

Bug: 160002800
Test: adb shell
./data/fuzz/arm64/computepipe_pixel_stream_manager_fuzzer/computepipe_pixel_stream_manager_fuzzer

Change-Id: I1b055e225c77c08d474d9bbf583fd71f3289da70
Merged-In: I1b055e225c77c08d474d9bbf583fd71f3289da70
(cherry picked from commit a913ced55f615d5c8e7ea0b047fef296389a4df8)
diff --git a/computepipe/tests/fuzz/Android.bp b/computepipe/tests/fuzz/Android.bp
index 6c54b64..ee95bb1 100644
--- a/computepipe/tests/fuzz/Android.bp
+++ b/computepipe/tests/fuzz/Android.bp
@@ -82,6 +82,21 @@
 }
 
 cc_fuzz {
+    name: "computepipe_pixel_stream_manager_fuzzer",
+    defaults: ["libcomputepipefuzz-defaults"],
+    srcs: [
+        "PixelStreamManagerFuzzer.cpp",
+    ],
+    shared_libs: [
+         "libprotobuf-cpp-full",
+    ],
+    static_libs: [
+        "libcomputepipeprotosfuzz",
+        "libprotobuf-mutator",
+    ],
+}
+
+cc_fuzz {
     name: "local_prebuild_graph_fuzzer",
     defaults: ["libcomputepipefuzz-defaults"],
     cppflags:[
diff --git a/computepipe/tests/fuzz/PixelStreamManagerFuzzer.cpp b/computepipe/tests/fuzz/PixelStreamManagerFuzzer.cpp
new file mode 100644
index 0000000..1a8c83e
--- /dev/null
+++ b/computepipe/tests/fuzz/PixelStreamManagerFuzzer.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <vndk/hardware_buffer.h>
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include "EventGenerator.h"
+#include "InputFrame.h"
+#include "MockEngine.h"
+#include "OutputConfig.pb.h"
+#include "PixelFormatUtils.h"
+#include "PixelStreamManager.h"
+#include "RunnerComponent.h"
+#include "StreamEngineInterface.h"
+#include "StreamManager.h"
+#include "src/libfuzzer/libfuzzer_macro.h"
+#include "types/Status.h"
+
+using ::android::automotive::computepipe::runner::generator::DefaultEvent;
+using ::testing::Return;
+
+namespace android {
+namespace automotive {
+namespace computepipe {
+namespace runner {
+namespace stream_manager {
+namespace {
+
+enum State {
+    RESET = 0,
+    RUN,
+    STOP_WITH_FLUSH,
+    STOP_IMMEDIATE,
+    QUEUE_PACKET,
+    FREE_PACKET,
+    CLONE_PACKET
+};
+
+std::pair<std::shared_ptr<MockEngine>, std::unique_ptr<StreamManager>> CreateStreamManagerAndEngine(
+        int maxInFlightPackets) {
+    StreamManagerFactory factory;
+    proto::OutputConfig outputConfig;
+    outputConfig.set_type(proto::PacketType::PIXEL_DATA);
+    outputConfig.set_stream_name("pixel_stream");
+    std::shared_ptr<MockEngine> mockEngine = std::make_shared<MockEngine>();
+    std::unique_ptr<StreamManager> manager =
+            factory.getStreamManager(outputConfig, mockEngine, maxInFlightPackets);
+
+    return std::pair(mockEngine, std::move(manager));
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    if (size < sizeof(uint32_t)) {
+        return 0;
+    }
+
+    FuzzedDataProvider fdp(data, size);
+    int maxInFlightPackets = fdp.ConsumeIntegral<uint32_t>();
+    auto [mockEngine, manager] = CreateStreamManagerAndEngine(maxInFlightPackets);
+    std::vector<uint8_t> pixelData(16 * 16 * 3, 100);
+    InputFrame frame(16, 16, PixelFormat::RGB, 16 * 3, &pixelData[0]);
+    std::shared_ptr<MemHandle> memHandle;
+    EXPECT_CALL((*mockEngine), dispatchPacket)
+            .Times(testing::AnyNumber())
+            .WillRepeatedly(
+                    testing::DoAll(testing::SaveArg<0>(&memHandle), (Return(Status::SUCCESS))));
+
+    while (fdp.remaining_bytes() > 0) {
+        uint8_t state = fdp.ConsumeIntegralInRange<uint8_t>(RESET, CLONE_PACKET);
+        DefaultEvent e = DefaultEvent::generateEntryEvent(static_cast<DefaultEvent::Phase>(state));
+
+        switch (state) {
+            case RESET:
+            case RUN: {
+                manager->handleExecutionPhase(e);
+                break;
+            }
+            case STOP_WITH_FLUSH: {
+                EXPECT_CALL((*mockEngine), notifyEndOfStream).Times(testing::AtMost(1));
+                manager->handleStopWithFlushPhase(e);
+                sleep(1);
+                break;
+            }
+            case STOP_IMMEDIATE: {
+                EXPECT_CALL((*mockEngine), notifyEndOfStream).Times(testing::AtMost(1));
+                manager->handleStopImmediatePhase(e);
+                sleep(1);
+                break;
+            }
+            case QUEUE_PACKET: {
+                manager->queuePacket(frame, rand());
+                sleep(1);
+                break;
+            }
+            case FREE_PACKET: {
+                if (memHandle != nullptr) {
+                    manager->freePacket(memHandle->getBufferId());
+                }
+                break;
+            }
+            case CLONE_PACKET: {
+                manager->clonePacket(memHandle);
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+}  // namespace
+}  // namespace stream_manager
+}  // namespace runner
+}  // namespace computepipe
+}  // namespace automotive
+}  // namespace android