summaryrefslogtreecommitdiff
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/eco/ECOData.cpp138
-rw-r--r--media/eco/include/eco/ECOData.h102
-rw-r--r--media/eco/include/eco/ECODataKey.h6
-rw-r--r--media/eco/tests/Android.bp19
-rw-r--r--media/eco/tests/EcoDataTest.cpp303
-rw-r--r--media/eco/tests/run_all_unit_tests.sh10
6 files changed, 573 insertions, 5 deletions
diff --git a/media/eco/ECOData.cpp b/media/eco/ECOData.cpp
index bb3fe1a..0f32e53 100644
--- a/media/eco/ECOData.cpp
+++ b/media/eco/ECOData.cpp
@@ -19,10 +19,12 @@
#include <utils/Errors.h>
#include <utils/Log.h>
+#include <string>
#include <binder/Parcel.h>
#include "eco/ECOData.h"
+#include "eco/ECODataKey.h"
namespace android {
namespace media {
@@ -33,15 +35,151 @@ using namespace ::android;
status_t ECOData::readFromParcel(const Parcel* parcel) {
parcel->readInt32(&mDataType);
parcel->readInt64(&mDataTimeUs);
+ // TODO(hkuang): Add the implenmentation of reading all keys.
return NO_ERROR;
}
status_t ECOData::writeToParcel(Parcel* parcel) const {
parcel->writeInt32(mDataType);
parcel->writeInt64(mDataTimeUs);
+ // TODO(hkuang): Add the implenmentation of writing all keys.
return NO_ERROR;
}
+void ECOData::init() {
+ mKeyValueStore[ECO_DATA_KEY_TYPE] = mDataType;
+ mKeyValueStore[ECO_DATA_KEY_TIME_US] = mDataTimeUs;
+}
+
+int32_t ECOData::getDataType() {
+ return mDataType;
+}
+
+int64_t ECOData::getDataTimeUs() {
+ return mDataTimeUs;
+}
+
+// Inserts a new key into store if the key does not exist yet. Otherwise, this will override the
+// existing key's value.
+ECODataStatus ECOData::setString(const std::string& key, const std::string& value) {
+ if (key.empty() || value.empty()) {
+ return ECODataStatus::INVALID_ARGUMENT;
+ }
+
+ mKeyValueStore[key] = value;
+
+ // TODO(hkuang): Check the valueType is valid for the key.
+ return ECODataStatus::OK;
+}
+
+ECODataStatus ECOData::findString(const std::string& key, std::string* value) const {
+ if (key.empty()) {
+ return ECODataStatus::INVALID_ARGUMENT;
+ }
+
+ // Check if the key exists.
+ if (mKeyValueStore.find(key) == mKeyValueStore.end()) {
+ return ECODataStatus::KEY_NOT_EXIST;
+ }
+
+ // Safely access the value.
+ const std::string& entryValue = std::get<std::string>(mKeyValueStore.at(key));
+ value->assign(entryValue);
+
+ return ECODataStatus::OK;
+}
+
+// Inserts a new key into store if the key does not exist yet. Otherwise, this will override the
+// existing key's value.
+template <typename T>
+ECODataStatus ECOData::setValue(const std::string& key, T value) {
+ if (key.empty()) {
+ return ECODataStatus::INVALID_ARGUMENT;
+ }
+
+ mKeyValueStore[key] = value;
+ return ECODataStatus::OK;
+}
+
+template <typename T>
+ECODataStatus ECOData::findValue(const std::string& key, T* out) const {
+ if (key.empty() || out == nullptr) {
+ return ECODataStatus::INVALID_ARGUMENT;
+ }
+
+ if (mKeyValueStore.find(key) == mKeyValueStore.end()) {
+ return ECODataStatus::KEY_NOT_EXIST;
+ }
+
+ // Safely access the value.
+ *out = std::get<T>(mKeyValueStore.at(key));
+
+ return ECODataStatus::OK;
+}
+
+ECODataStatus ECOData::setInt32(const std::string& key, int32_t value) {
+ return setValue<int32_t>(key, value);
+}
+
+ECODataStatus ECOData::findInt32(const std::string& key, int32_t* out) const {
+ return findValue<int32_t>(key, out);
+}
+
+ECODataStatus ECOData::setInt64(const std::string& key, int64_t value) {
+ return setValue<int64_t>(key, value);
+}
+
+ECODataStatus ECOData::findInt64(const std::string& key, int64_t* out) const {
+ return findValue<int64_t>(key, out);
+}
+
+ECODataStatus ECOData::setDouble(const std::string& key, double value) {
+ return setValue<double>(key, value);
+}
+
+ECODataStatus ECOData::findDouble(const std::string& key, double* out) const {
+ return findValue<double>(key, out);
+}
+
+ECODataStatus ECOData::setSize(const std::string& key, size_t value) {
+ return setValue<size_t>(key, value);
+}
+
+ECODataStatus ECOData::findSize(const std::string& key, size_t* out) const {
+ return findValue<size_t>(key, out);
+}
+
+ECODataStatus ECOData::setFloat(const std::string& key, float value) {
+ return setValue<float>(key, value);
+}
+
+ECODataStatus ECOData::findFloat(const std::string& key, float* out) const {
+ return findValue<float>(key, out);
+}
+
+ECODataStatus ECOData::set(const std::string& key, const ECOData::ECODataValueType& value) {
+ if (key.empty()) {
+ return ECODataStatus::INVALID_ARGUMENT;
+ }
+ mKeyValueStore[key] = value;
+ return ECODataStatus::OK;
+}
+
+ECODataStatus ECOData::find(const std::string& key, ECOData::ECODataValueType* out) const {
+ if (key.empty() || out == nullptr) {
+ return ECODataStatus::INVALID_ARGUMENT;
+ }
+
+ if (mKeyValueStore.find(key) == mKeyValueStore.end()) {
+ return ECODataStatus::KEY_NOT_EXIST;
+ }
+
+ // Safely access the value.
+ *out = mKeyValueStore.at(key);
+
+ return ECODataStatus::OK;
+}
+
} // namespace eco
} // namespace media
} // namespace android \ No newline at end of file
diff --git a/media/eco/include/eco/ECOData.h b/media/eco/include/eco/ECOData.h
index 9c17320..37b048c 100644
--- a/media/eco/include/eco/ECOData.h
+++ b/media/eco/include/eco/ECOData.h
@@ -19,11 +19,23 @@
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
+#include <string>
+#include <unordered_map>
+#include <variant>
namespace android {
namespace media {
namespace eco {
+enum class ECODataStatus {
+ OK,
+ FAIL_TO_INSERT,
+ INVALID_ECODATA_TYPE,
+ KEY_NOT_EXIST,
+ INVALID_VALUE_TYPE,
+ INVALID_ARGUMENT,
+};
+
/**
* ECOData is the container for all messages passed between different components in ECOService.
* All messages in ECOServices are represented by a list of key-value pairs.
@@ -31,14 +43,40 @@ namespace eco {
* "bit-rate" -> 22000000
* "Provider-Name" -> "QCOM-Video-Encoder".
* "avg-frame-qp" -> 40
-* ECOData follows the same design pattern of AMessage and Metadata in Media Framework.
-* TODO(hkuang): Add the implementation and sample usage.
+* ECOData follows the same design pattern of AMessage and Metadata in Media Framework. The key
+* must be non-empty string. Below are the supported data types:
+*
+* // Item types set/find function suffixes
+* // ==========================================
+* // int32_t Int32
+* // int64_t Int64
+* // size_t Size
+* // float Float
+* // double Double
+* // String String
+*
+* ECOData does not support duplicate keys with different values. When inserting a key-value pair,
+* a new entry will be created if the key does not exist. Othewise, they key's value will be
+* overwritten with the new value.
+*
+* Sample usage:
+*
+* // Create the ECOData
+* std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+*
+* // Set the encoder name.
+* data->setString("stats-encoder-type", "google-avc");
+*
+* // Set encoding bitrate.
+* data->setInt32("stats-encoder-target-bitrate-bps", 22000000);
*/
class ECOData : public Parcelable {
public:
- ECOData() : mDataType(0), mDataTimeUs(-1) {}
- ECOData(int32_t type) : mDataType(type), mDataTimeUs(-1) {}
- ECOData(int32_t type, int64_t timeUs) : mDataType(type), mDataTimeUs(timeUs) {}
+ using ECODataValueType = std::variant<int32_t, int64_t, size_t, float, double, std::string>;
+
+ ECOData() : mDataType(0), mDataTimeUs(-1) { init(); }
+ ECOData(int32_t type) : mDataType(type), mDataTimeUs(-1) { init(); }
+ ECOData(int32_t type, int64_t timeUs) : mDataType(type), mDataTimeUs(timeUs) { init(); }
// Constants for mDataType.
enum {
@@ -53,13 +91,58 @@ public:
DATA_TYPE_INFO_LISTENER_OPTON = 4,
};
+ // set/find functions that could be used for all the value types.
+ ECODataStatus set(const std::string& key, const ECODataValueType& value);
+ ECODataStatus find(const std::string& key, ECODataValueType* out) const;
+
+ // Convenient set/find functions for string value type.
+ ECODataStatus setString(const std::string& key, const std::string& value);
+ ECODataStatus findString(const std::string& key, std::string* out) const;
+
+ // Convenient set/find functions for int32_t value type.
+ ECODataStatus setInt32(const std::string& key, int32_t value);
+ ECODataStatus findInt32(const std::string& key, int32_t* out) const;
+
+ // Convenient set/find functions for int64_t value type.
+ ECODataStatus setInt64(const std::string& key, int64_t value);
+ ECODataStatus findInt64(const std::string& key, int64_t* out) const;
+
+ // Convenient set/find functions for float value type.
+ ECODataStatus setFloat(const std::string& key, float value);
+ ECODataStatus findFloat(const std::string& key, float* out) const;
+
+ // Convenient set/find functions for double value type.
+ ECODataStatus setDouble(const std::string& key, double value);
+ ECODataStatus findDouble(const std::string& key, double* out) const;
+
+ // Convenient set/find functions for size_t value type.
+ ECODataStatus setSize(const std::string& key, size_t value);
+ ECODataStatus findSize(const std::string& key, size_t* out) const;
+
/**
* Serialization over Binder
*/
status_t readFromParcel(const Parcel* parcel) override;
status_t writeToParcel(Parcel* parcel) const override;
+ /* Returns the type of the data. */
+ int32_t getDataType();
+
+ /* Returns the timestamp associated with the data. */
+ int64_t getDataTimeUs();
+
+ /* Sets the type of the data. */
+ void setDataType(int32_t type);
+
+ /* Sets the timestamp associated with the data. */
+ void setDataTimeUs();
+
+ /* Gets the number of keys in the ECOData. */
+ size_t getNumOfEntries() { return mKeyValueStore.size(); }
+
private:
+ void init();
+
/* The type of the data */
int32_t mDataType;
@@ -67,6 +150,15 @@ private:
// boottime time base. This is only used when the data type is stats or info. -1 means
// unavailable.
int64_t mDataTimeUs;
+
+ // Internal store for the key value pairs.
+ std::unordered_map<std::string, ECODataValueType> mKeyValueStore;
+
+ template <typename T>
+ ECODataStatus setValue(const std::string& key, T value);
+
+ template <typename T>
+ ECODataStatus findValue(const std::string& key, T* out) const;
};
} // namespace eco
diff --git a/media/eco/include/eco/ECODataKey.h b/media/eco/include/eco/ECODataKey.h
index 7945ea0..0856e01 100644
--- a/media/eco/include/eco/ECODataKey.h
+++ b/media/eco/include/eco/ECODataKey.h
@@ -86,6 +86,12 @@ constexpr char INFO_KEY_FRAME_TYPE[] = "info-frame-type";
constexpr char INFO_KEY_FRAME_SIZE_BYTES[] = "info-frame-size-bytes";
constexpr char INFO_KEY_CURRENT_BITRATE_BPS[] = "info-current-bitrate-bps";
+// ================================================================================================
+// Standard ECOData keys.
+// ================================================================================================
+constexpr char ECO_DATA_KEY_TYPE[] = "eco-data-type";
+constexpr char ECO_DATA_KEY_TIME_US[] = "eco-data-time-us";
+
} // namespace eco
} // namespace media
} // namespace android
diff --git a/media/eco/tests/Android.bp b/media/eco/tests/Android.bp
new file mode 100644
index 0000000..543885c
--- /dev/null
+++ b/media/eco/tests/Android.bp
@@ -0,0 +1,19 @@
+cc_defaults{
+ name : "libmedia_ecoservice_tests_defaults",
+ cflags : [
+ "-Wall",
+ "-Werror",
+ ],
+}
+
+cc_test {
+ name: "EcoDataTest",
+ defaults: ["libmedia_ecoservice_tests_defaults"],
+ srcs: ["EcoDataTest.cpp"],
+ shared_libs: [
+ "libbinder",
+ "libcutils",
+ "libutils",
+ "libmedia_ecoservice",
+ ],
+}
diff --git a/media/eco/tests/EcoDataTest.cpp b/media/eco/tests/EcoDataTest.cpp
new file mode 100644
index 0000000..fb9e2a1
--- /dev/null
+++ b/media/eco/tests/EcoDataTest.cpp
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// Unit Test for EcoData.
+
+#include <math.h>
+#include <stdlib.h>
+
+#include <android-base/unique_fd.h>
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+#include <cutils/ashmem.h>
+#include <gtest/gtest.h>
+#include <sys/mman.h>
+
+#include "eco/ECOData.h"
+#include "eco/ECODataKey.h"
+
+namespace android {
+namespace media {
+namespace eco {
+
+TEST(EcoDataTest, TestConstructor1) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>();
+ EXPECT_EQ(data->getDataType(), ECOData::DATA_TYPE_UNKNOWN);
+ EXPECT_EQ(data->getDataTimeUs(), -1);
+
+ int32_t type;
+ EXPECT_TRUE(data->findInt32(ECO_DATA_KEY_TYPE, &type) == ECODataStatus::OK);
+ EXPECT_EQ(type, ECOData::DATA_TYPE_UNKNOWN);
+
+ int64_t time;
+ EXPECT_TRUE(data->findInt64(ECO_DATA_KEY_TIME_US, &time) == ECODataStatus::OK);
+ EXPECT_EQ(time, -1);
+}
+
+TEST(EcoDataTest, TestConstructor2) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS);
+ EXPECT_EQ(data->getDataType(), ECOData::DATA_TYPE_STATS);
+ EXPECT_EQ(data->getDataTimeUs(), -1);
+}
+
+TEST(EcoDataTest, TestConstructor3) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+ EXPECT_EQ(data->getDataType(), ECOData::DATA_TYPE_STATS);
+ EXPECT_EQ(data->getDataTimeUs(), 1000);
+}
+
+TEST(EcoDataTest, TestNormalSetAndFindString) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ data->setString(STATS_KEY_ENCODER_TYPE, "avc");
+ std::string testValue;
+ EXPECT_TRUE(data->findString(STATS_KEY_ENCODER_TYPE, &testValue) == ECODataStatus::OK);
+ EXPECT_EQ(testValue, "avc");
+
+ // Override existing key.
+ data->setString(STATS_KEY_ENCODER_TYPE, "hevc");
+ EXPECT_EQ(data->findString(STATS_KEY_ENCODER_TYPE, &testValue), ECODataStatus::OK);
+ EXPECT_EQ(testValue, "hevc");
+}
+
+TEST(EcoDataTest, TestSetAndFindMultipleString) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ std::unordered_map<std::string, std::string> inputEntries = {
+ {"name1", "avc"}, {"name2", "avc2"}, {"name3", "avc3"}, {"name4", "avc4"},
+ {"name5", "avc5"}, {"name6", "avc6"}, {"name7", "avc7"}, {"name8", "avc8"},
+ {"name9", "avc9"}, {"name10", "avc10"}, {"name11", "avc11"}, {"name12", "avc12"}};
+ for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
+ data->setString(it->first, it->second);
+ }
+
+ // Checks if the string exist in the ECOData.
+ for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
+ std::string testValue;
+ EXPECT_TRUE(data->findString(it->first, &testValue) == ECODataStatus::OK);
+ EXPECT_EQ(testValue, it->second);
+ }
+}
+
+TEST(EcoDataTest, TestSetAndFindInvalidString) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ // Test read to null ptr and expect failure
+ EXPECT_TRUE(data->findString("encoder-name", nullptr) != ECODataStatus::OK);
+
+ // Test find non-existing key and expect failure.
+ std::string testValue;
+ EXPECT_TRUE(data->findString("encoder-name", &testValue) != ECODataStatus::OK);
+
+ // Test set empty key and expect failure
+ EXPECT_TRUE(data->setString("", "avc") != ECODataStatus::OK);
+
+ // Test read empty key and expect failure
+ EXPECT_TRUE(data->findString("", &testValue) != ECODataStatus::OK);
+}
+
+TEST(EcoDataTest, TestNormalSetAndFindInt32) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ data->setInt32(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, 2000000);
+ int32_t testValue;
+ EXPECT_TRUE(data->findInt32(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, &testValue) ==
+ ECODataStatus::OK);
+ EXPECT_EQ(testValue, 2000000);
+
+ // Override existing key.
+ data->setInt32(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, 2200000);
+ EXPECT_EQ(data->findInt32(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, &testValue), ECODataStatus::OK);
+ EXPECT_EQ(testValue, 2200000);
+}
+
+TEST(EcoDataTest, TestSetAndFindMultipleInt32) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ std::unordered_map<std::string, int32_t> inputEntries = {
+ {"name1", 100}, {"name2", 200}, {"name3", 300}, {"name4", 400},
+ {"name5", 500}, {"name6", 600}, {"name7", 700}, {"name8", 800},
+ {"name9", 900}, {"name10", 10000}, {"name11", 110000}, {"name12", 120000}};
+ for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
+ data->setInt32(it->first, it->second);
+ }
+
+ // Checks if the string exist in the ECOData.
+ for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
+ int32_t testValue;
+ EXPECT_TRUE(data->findInt32(it->first, &testValue) == ECODataStatus::OK);
+ EXPECT_EQ(testValue, it->second);
+ }
+}
+
+TEST(EcoDataTest, TestSetAndFindInvalidInt32) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ // Test read to null ptr and expect failure
+ EXPECT_TRUE(data->findInt32("encoder-name", nullptr) != ECODataStatus::OK);
+
+ // Test find non-existing key and expect failure.
+ int32_t testValue;
+ EXPECT_TRUE(data->findInt32("encoder-name", &testValue) != ECODataStatus::OK);
+
+ // Test set empty key and expect failure
+ EXPECT_TRUE(data->setInt32("", 1000) != ECODataStatus::OK);
+
+ // Test read empty key and expect failure
+ EXPECT_TRUE(data->findInt32("", &testValue) != ECODataStatus::OK);
+}
+
+TEST(EcoDataTest, TestNormalSetAndFindInt64) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ data->setInt64(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, 2000000);
+ int64_t testValue;
+ EXPECT_TRUE(data->findInt64(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, &testValue) ==
+ ECODataStatus::OK);
+ EXPECT_EQ(testValue, 2000000);
+
+ // Override existing key.
+ data->setInt64(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, 2200000);
+ EXPECT_EQ(data->findInt64(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, &testValue), ECODataStatus::OK);
+ EXPECT_EQ(testValue, 2200000);
+}
+
+TEST(EcoDataTest, TestNormalSetAndFindMultipleInt64) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ std::unordered_map<std::string, int64_t> inputEntries = {
+ {"name1", 100}, {"name2", 200}, {"name3", 300}, {"name4", 400},
+ {"name5", 500}, {"name6", 600}, {"name7", 700}, {"name8", 800},
+ {"name9", 900}, {"name10", 10000}, {"name11", 110000}, {"name12", 120000}};
+ for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
+ data->setInt64(it->first, it->second);
+ }
+
+ // Checks if the string exist in the ECOData.
+ for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
+ int64_t testValue;
+ EXPECT_TRUE(data->findInt64(it->first, &testValue) == ECODataStatus::OK);
+ EXPECT_EQ(testValue, it->second);
+ }
+}
+
+TEST(EcoDataTest, TestSetAndFindInvalidInt64) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ // Test read to null ptr and expect failure
+ EXPECT_TRUE(data->findInt64("encoder-name", nullptr) != ECODataStatus::OK);
+
+ // Test find non-existing key and expect failure.
+ int64_t testValue;
+ EXPECT_TRUE(data->findInt64("encoder-name", &testValue) != ECODataStatus::OK);
+
+ // Test set empty key and expect failure
+ EXPECT_TRUE(data->setInt64("", 1000) != ECODataStatus::OK);
+
+ // Test read empty key and expect failure
+ EXPECT_TRUE(data->findInt64("", &testValue) != ECODataStatus::OK);
+}
+
+TEST(EcoDataTest, TestNormalSetAndFindFloat) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ data->setFloat(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, 2000000.0);
+ float testValue;
+ EXPECT_TRUE(data->findFloat(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, &testValue) ==
+ ECODataStatus::OK);
+ EXPECT_FLOAT_EQ(testValue, 2000000.0);
+
+ // Override existing key.
+ data->setFloat(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, 2200000.0);
+ EXPECT_TRUE(data->findFloat(STATS_KEY_ENCODER_TARGET_BITRATE_BPS, &testValue) ==
+ ECODataStatus::OK);
+ EXPECT_FLOAT_EQ(testValue, 2200000.0);
+}
+
+TEST(EcoDataTest, TestNormalSetAndFindMultipleFloat) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ std::unordered_map<std::string, float> inputEntries = {
+ {"name1", 100.0}, {"name2", 200.0}, {"name3", 300.0}, {"name4", 400.0},
+ {"name5", 500.0}, {"name6", 600.0}, {"name7", 700.0}, {"name8", 800.0},
+ {"name9", 900.0}, {"name10", 10000.0}, {"name11", 110000.0}, {"name12", 120000.0}};
+ for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
+ data->setFloat(it->first, it->second);
+ }
+
+ // Checks if the string exist in the ECOData.
+ for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
+ float testValue;
+ EXPECT_TRUE(data->findFloat(it->first, &testValue) == ECODataStatus::OK);
+ EXPECT_FLOAT_EQ(testValue, it->second);
+ }
+}
+
+TEST(EcoDataTest, TestSetAndFindInvalidFloat) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ // Test read to null ptr and expect failure
+ EXPECT_TRUE(data->findFloat("encoder-name", nullptr) != ECODataStatus::OK);
+
+ // Test find non-existing key and expect failure.
+ float testValue;
+ EXPECT_TRUE(data->findFloat("encoder-name", &testValue) != ECODataStatus::OK);
+
+ // Test set empty key and expect failure
+ EXPECT_TRUE(data->setFloat("", 1000.0) != ECODataStatus::OK);
+
+ // Test read empty key and expect failure
+ EXPECT_TRUE(data->findFloat("", &testValue) != ECODataStatus::OK);
+}
+
+TEST(EcoDataTest, TestNormalSetAndFindMixedDataType) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ std::unordered_map<std::string, ECOData::ECODataValueType> inputEntries = {
+ {"name1", "google-encoder"}, {"name2", "avc"}, {"profile", 1}, {"level", 2},
+ {"framerate", 4.1}, {"kfi", 30}};
+ for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
+ data->set(it->first, it->second);
+ }
+
+ // Checks if the string exist in the ECOData.
+ for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
+ ECOData::ECODataValueType testValue;
+ EXPECT_TRUE(data->find(it->first, &testValue) == ECODataStatus::OK);
+ EXPECT_EQ(testValue, it->second);
+ }
+}
+
+TEST(EcoDataTest, TestSetAndFindInvalidDataType) {
+ std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
+
+ // Test read to null ptr and expect failure
+ EXPECT_TRUE(data->find("encoder-name", nullptr) != ECODataStatus::OK);
+
+ // Test find non-existing key and expect failure.
+ ECOData::ECODataValueType testValue;
+ EXPECT_TRUE(data->find("encoder-name2", &testValue) != ECODataStatus::OK);
+
+ // Test set empty key and expect failure
+ EXPECT_TRUE(data->set("", 1000) != ECODataStatus::OK);
+
+ // Test read empty key and expect failure
+ EXPECT_TRUE(data->find("", &testValue) != ECODataStatus::OK);
+}
+
+} // namespace eco
+} // namespace media
+} // namespace android \ No newline at end of file
diff --git a/media/eco/tests/run_all_unit_tests.sh b/media/eco/tests/run_all_unit_tests.sh
new file mode 100644
index 0000000..0b5fee0
--- /dev/null
+++ b/media/eco/tests/run_all_unit_tests.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+ echo "Android build environment not set"
+ exit -1
+fi
+
+echo "waiting for device"
+adb root && adb wait-for-device remount && adb sync
+
+adb shell /data/nativetest/EcoDataTest/EcoDataTest