Move Codec2-related code from hardware/google/av
Test: None
Bug: 112362730
Change-Id: Ie2f8ff431d65c40333f267ab9877d47089adeea4
diff --git a/media/codec2/faultinjection/Android.bp b/media/codec2/faultinjection/Android.bp
new file mode 100644
index 0000000..06e5c1b
--- /dev/null
+++ b/media/codec2/faultinjection/Android.bp
@@ -0,0 +1,32 @@
+cc_library_shared {
+ name: "libc2_component_wrapper",
+ vendor_available: true,
+
+ srcs: [
+ "C2ComponentWrapper.cpp",
+ "SimpleMethodState.cpp",
+ ],
+
+ shared_libs: [
+ "libcutils",
+ "liblog",
+ "libstagefright_codec2",
+ "libstagefright_codec2_vndk",
+ "libstagefright_foundation",
+ "libutils",
+ ],
+
+ sanitize: {
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ cfi: true,
+ diag: {
+ cfi: true,
+ },
+ },
+
+ ldflags: ["-Wl,-Bsymbolic"],
+}
+
diff --git a/media/codec2/faultinjection/C2ComponentWrapper.cpp b/media/codec2/faultinjection/C2ComponentWrapper.cpp
new file mode 100644
index 0000000..c45f8bf
--- /dev/null
+++ b/media/codec2/faultinjection/C2ComponentWrapper.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "C2ComponentWrapper"
+
+#include <chrono>
+#include <functional>
+#include <thread>
+
+#include <C2ComponentWrapper.h>
+#include <C2Config.h>
+#include <C2PlatformSupport.h>
+
+namespace android {
+
+namespace {
+
+using namespace std::chrono_literals;
+
+c2_status_t WrapSimpleMethod(
+ std::function<c2_status_t(void)> op, const SimpleMethodState &state) {
+ c2_status_t result = C2_OK;
+ switch (state.getMode()) {
+ case SimpleMethodState::EXECUTE:
+ result = op();
+ break;
+ case SimpleMethodState::NO_OP:
+ break;
+ case SimpleMethodState::HANG:
+ while (true) {
+ std::this_thread::sleep_for(1s);
+ }
+ break;
+ }
+ (void)state.overrideResult(&result);
+ return result;
+}
+
+} // namespace
+
+C2ComponentWrapper::Injecter::Injecter(C2ComponentWrapper *thiz) : mThiz(thiz) {}
+
+SimpleMethodState::Injecter C2ComponentWrapper::Injecter::start() {
+ return SimpleMethodState::Injecter(&mThiz->mStartState);
+}
+
+C2ComponentWrapper::Listener::Listener(
+ const std::shared_ptr<C2Component::Listener> &listener) : mListener(listener) {}
+
+void C2ComponentWrapper::Listener::onWorkDone_nb(std::weak_ptr<C2Component> component,
+ std::list<std::unique_ptr<C2Work>> workItems) {
+ mListener->onWorkDone_nb(component, std::move(workItems));
+}
+
+void C2ComponentWrapper::Listener::onTripped_nb(std::weak_ptr<C2Component> component,
+ std::vector<std::shared_ptr<C2SettingResult>> settingResult) {
+ mListener->onTripped_nb(component,settingResult);
+}
+
+void C2ComponentWrapper::Listener::onError_nb(
+ std::weak_ptr<C2Component> component, uint32_t errorCode) {
+ mListener->onError_nb(component, errorCode);
+}
+
+C2ComponentWrapper::C2ComponentWrapper(
+ const std::shared_ptr<C2Component> &comp) : mComp(comp) {}
+
+c2_status_t C2ComponentWrapper::setListener_vb(
+ const std::shared_ptr<C2Component::Listener> &listener, c2_blocking_t mayBlock) {
+ mListener = std::make_shared<Listener>(listener);
+ return mComp->setListener_vb(mListener, mayBlock);
+}
+
+c2_status_t C2ComponentWrapper::queue_nb(std::list<std::unique_ptr<C2Work>>* const items) {
+ return mComp->queue_nb(items);
+}
+
+c2_status_t C2ComponentWrapper::announce_nb(const std::vector<C2WorkOutline> &items) {
+ return mComp->announce_nb(items);
+}
+
+c2_status_t C2ComponentWrapper::flush_sm(
+ C2Component::flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) {
+ return mComp->flush_sm(mode, flushedWork);
+}
+
+c2_status_t C2ComponentWrapper::drain_nb(C2Component::drain_mode_t mode) {
+ return mComp->drain_nb(mode);
+}
+
+c2_status_t C2ComponentWrapper::start() {
+ return WrapSimpleMethod([this] { return mComp->start(); }, mStartState);
+}
+
+c2_status_t C2ComponentWrapper::stop() {
+ return mComp->stop();
+}
+
+c2_status_t C2ComponentWrapper::reset() {
+ return mComp->reset();
+}
+
+c2_status_t C2ComponentWrapper::release() {
+ return mComp->release();
+}
+
+std::shared_ptr<C2ComponentInterface> C2ComponentWrapper::intf(){
+ return mComp->intf();
+}
+
+C2ComponentWrapper::Injecter C2ComponentWrapper::inject() {
+ return Injecter(this);
+}
+
+} // namespace android
diff --git a/media/codec2/faultinjection/C2ComponentWrapper.h b/media/codec2/faultinjection/C2ComponentWrapper.h
new file mode 100644
index 0000000..737350d
--- /dev/null
+++ b/media/codec2/faultinjection/C2ComponentWrapper.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef C2_COMPONENT_WRAPPER_H_
+#define C2_COMPONENT_WRAPPER_H_
+
+#include <C2Component.h>
+
+#include "SimpleMethodState.h"
+
+namespace android {
+
+/**
+ * Creates a Wrapper around the class C2Component and its methods. The wrapper is used to
+ * simulate errors in the android media components by fault injection technique.
+ * This is done to check how the framework handles the error situation.
+ */
+class C2ComponentWrapper
+ : public C2Component, public std::enable_shared_from_this<C2ComponentWrapper> {
+public:
+ class Injecter {
+ public:
+ explicit Injecter(C2ComponentWrapper *thiz);
+
+ SimpleMethodState::Injecter start();
+ private:
+ C2ComponentWrapper *const mThiz;
+ };
+
+ /**
+ * A wrapper around the listener class inside C2Component class.
+ */
+ class Listener : public C2Component::Listener {
+ public:
+ explicit Listener(const std::shared_ptr<C2Component::Listener> &listener);
+ virtual ~Listener() = default;
+
+ void onWorkDone_nb(std::weak_ptr<C2Component> component,
+ std::list<std::unique_ptr<C2Work>> workItems) override;
+ void onTripped_nb(std::weak_ptr<C2Component> component,
+ std::vector<std::shared_ptr<C2SettingResult>> settingResult) override;
+ void onError_nb(std::weak_ptr<C2Component> component, uint32_t errorCode) override;
+
+ private:
+ std::shared_ptr<C2Component::Listener> mListener;
+ };
+
+ explicit C2ComponentWrapper(const std::shared_ptr<C2Component> &comp);
+ virtual ~C2ComponentWrapper() = default;
+
+ virtual c2_status_t setListener_vb(
+ const std::shared_ptr<C2Component::Listener> &listener,
+ c2_blocking_t mayBlock) override;
+ virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override;
+ virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) override;
+ virtual c2_status_t flush_sm(
+ flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) override;
+ virtual c2_status_t drain_nb(drain_mode_t mode) override;
+ virtual c2_status_t start() override;
+ virtual c2_status_t stop() override;
+ virtual c2_status_t reset() override;
+ virtual c2_status_t release() override;
+ virtual std::shared_ptr<C2ComponentInterface> intf() override;
+
+ Injecter inject();
+
+private:
+ std::shared_ptr<Listener> mListener;
+ std::shared_ptr<C2Component> mComp;
+
+ SimpleMethodState mStartState;
+};
+
+} // namespace android
+
+#endif // C2_COMPONENT_WRAPPER_H_
diff --git a/media/codec2/faultinjection/SimpleMethodState.cpp b/media/codec2/faultinjection/SimpleMethodState.cpp
new file mode 100644
index 0000000..179d64e
--- /dev/null
+++ b/media/codec2/faultinjection/SimpleMethodState.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "SimpleMethodState"
+#include <log/log.h>
+
+#include "SimpleMethodState.h"
+
+namespace android {
+
+SimpleMethodState::Injecter::Injecter(SimpleMethodState *thiz) : mThiz(thiz) {}
+
+void SimpleMethodState::Injecter::hang() {
+ mThiz->mMode = HANG;
+}
+
+void SimpleMethodState::Injecter::fail(c2_status_t err, bool execute) {
+ mThiz->mMode = execute ? EXECUTE : NO_OP;
+ mThiz->mOverride = true;
+ mThiz->mResultOverride = err;
+}
+
+SimpleMethodState::SimpleMethodState()
+ : mMode(EXECUTE), mOverride(false), mResultOverride(C2_OK) {}
+
+SimpleMethodState::Mode SimpleMethodState::getMode() const {
+ return mMode;
+}
+
+bool SimpleMethodState::overrideResult(c2_status_t *result) const {
+ if (!mOverride) {
+ return false;
+ }
+ *result = mResultOverride;
+ return true;
+}
+
+} // namespace android
diff --git a/media/codec2/faultinjection/SimpleMethodState.h b/media/codec2/faultinjection/SimpleMethodState.h
new file mode 100644
index 0000000..dc0459d
--- /dev/null
+++ b/media/codec2/faultinjection/SimpleMethodState.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef SIMPLE_METHOD_STATE_H_
+#define SIMPLE_METHOD_STATE_H_
+
+#include <C2.h>
+
+namespace android {
+
+/**
+ * State for a simple method which returns c2_status_t and takes no parameters.
+ */
+class SimpleMethodState {
+public:
+ enum Mode {
+ // Execute the normal operation
+ EXECUTE,
+ // Don't do anything
+ NO_OP,
+ // Hang; never return
+ HANG,
+ };
+
+ /**
+ * Injecter class that modifies the internal states of this class.
+ */
+ class Injecter {
+ public:
+ explicit Injecter(SimpleMethodState *thiz);
+
+ /**
+ * Hang the operation.
+ */
+ void hang();
+
+ /**
+ * Fail the operation with given params.
+ *
+ * \param err error code to replace the actual return value
+ * \param execute whether the wrapper should execute the operation
+ */
+ void fail(c2_status_t err, bool execute = false);
+
+ private:
+ SimpleMethodState *const mThiz;
+ };
+
+ SimpleMethodState();
+
+ /**
+ * Get execution mode.
+ */
+ Mode getMode() const;
+
+ /**
+ * Override result from running the operation if configured so.
+ */
+ bool overrideResult(c2_status_t *result) const;
+
+private:
+ Mode mMode;
+ bool mOverride;
+ c2_status_t mResultOverride;
+};
+
+} // namespace android
+
+#endif // SIMPLE_METHOD_STATE_H_