Merge changes from topics "face-hidl-2", "face-hidl-1"
* changes:
Add setter/getter for requireAttention
Update Face HIDL enroll method
diff --git a/configstore/1.2/Android.bp b/configstore/1.2/Android.bp
index a20eb34..cc5644c 100644
--- a/configstore/1.2/Android.bp
+++ b/configstore/1.2/Android.bp
@@ -12,6 +12,7 @@
interfaces: [
"android.hardware.configstore@1.1",
"android.hardware.configstore@1.0",
+ "android.hardware.graphics.common@1.1",
"android.hidl.base@1.0",
],
gen_java: true,
diff --git a/configstore/1.2/ISurfaceFlingerConfigs.hal b/configstore/1.2/ISurfaceFlingerConfigs.hal
index c32cc82..c879155 100644
--- a/configstore/1.2/ISurfaceFlingerConfigs.hal
+++ b/configstore/1.2/ISurfaceFlingerConfigs.hal
@@ -15,6 +15,8 @@
*/
package android.hardware.configstore@1.2;
+import android.hardware.graphics.common@1.1::Dataspace;
+import android.hardware.graphics.common@1.1::PixelFormat;
import @1.1::ISurfaceFlingerConfigs;
import @1.0::OptionalBool;
@@ -30,4 +32,27 @@
* return true.
*/
useColorManagement() generates (OptionalBool value);
+
+ /**
+ * Returns the default data space and default pixel format that
+ * SurfaceFlinger expects to receive and output.
+ * To determine the default data space and default pixel format,
+ * there are a few things we recommend to consider:
+ *
+ * 1. Hardware composer's capability to composite contents with the
+ * data space and pixel format efficiently;
+ * 2. Hardware composer's ability to composite contents when sRGB contents
+ * and the chosen data space contents coexist;
+ * 3. For better blending, consider using pixel format where the alpha
+ * channel has as many bits as the RGB color channel.
+ *
+ * @return dataSpace is the default data space that SurfaceFlinger expects.
+ * The data space must not be Dataspace::UNKNOWN, if unspecified,
+ * the default data space is Dataspace::V0_SRGB;
+ * @return pixelFormat is the default pixel format that SurfaceFlinger
+ * expects. If unspecified, the default pixel format is
+ * PixelFormat::RGBA_8888.
+ */
+ getCompositionPreference()
+ generates (Dataspace dataSpace, PixelFormat pixelFormat);
};
diff --git a/configstore/1.2/default/SurfaceFlingerConfigs.cpp b/configstore/1.2/default/SurfaceFlingerConfigs.cpp
index c7bd567..ae19dc0 100644
--- a/configstore/1.2/default/SurfaceFlingerConfigs.cpp
+++ b/configstore/1.2/default/SurfaceFlingerConfigs.cpp
@@ -17,6 +17,7 @@
#include "SurfaceFlingerConfigs.h"
#include <android/hardware/configstore/1.1/types.h>
+#include <android/hardware/graphics/common/1.1/types.h>
#include <log/log.h>
namespace android {
@@ -25,6 +26,9 @@
namespace V1_2 {
namespace implementation {
+using ::android::hardware::graphics::common::V1_1::Dataspace;
+using ::android::hardware::graphics::common::V1_1::PixelFormat;
+
// ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs implementation.
Return<void> SurfaceFlingerConfigs::vsyncEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) {
#ifdef VSYNC_EVENT_PHASE_OFFSET_NS
@@ -199,6 +203,25 @@
return Void();
}
+#ifdef COMPOSITION_DATA_SPACE
+static_assert(COMPOSITION_DATA_SPACE != 0, "Expected composition data space must not be UNKNOWN");
+#endif
+
+Return<void> SurfaceFlingerConfigs::getCompositionPreference(getCompositionPreference_cb _hidl_cb) {
+ Dataspace dataSpace = Dataspace::V0_SRGB;
+ PixelFormat pixelFormat = PixelFormat::RGBA_8888;
+
+#ifdef COMPOSITION_DATA_SPACE
+ dataSpace = static_cast<Dataspace>(COMPOSITION_DATA_SPACE);
+#endif
+
+#ifdef COMPOSITION_PIXEL_FORMAT
+ pixelFormat = static_cast<PixelFormat>(COMPOSITION_PIXEL_FORMAT);
+#endif
+ _hidl_cb(dataSpace, pixelFormat);
+ return Void();
+}
+
} // namespace implementation
} // namespace V1_2
} // namespace configstore
diff --git a/configstore/1.2/default/SurfaceFlingerConfigs.h b/configstore/1.2/default/SurfaceFlingerConfigs.h
index fe78789..7dd8f6d 100644
--- a/configstore/1.2/default/SurfaceFlingerConfigs.h
+++ b/configstore/1.2/default/SurfaceFlingerConfigs.h
@@ -52,6 +52,7 @@
// ::android::hardware::configstore::V1_2::ISurfaceFlingerConfigs follow implementation.
Return<void> useColorManagement(useColorManagement_cb _hidl_cb) override;
+ Return<void> getCompositionPreference(getCompositionPreference_cb _hidl_cb) override;
};
} // namespace implementation
diff --git a/configstore/1.2/default/surfaceflinger.mk b/configstore/1.2/default/surfaceflinger.mk
index 70be450..f323999 100644
--- a/configstore/1.2/default/surfaceflinger.mk
+++ b/configstore/1.2/default/surfaceflinger.mk
@@ -58,3 +58,11 @@
ifeq ($(TARGET_USE_COLOR_MANAGEMENT),true)
LOCAL_CFLAGS += -DUSE_COLOR_MANAGEMENT
endif
+
+ifneq ($(SF_COMPOSITION_DATA_SPACE),)
+ LOCAL_CFLAGS += -DCOMPOSITION_DATA_SPACE=$(SF_COMPOSITION_DATA_SPACE)
+endif
+
+ifneq ($(SF_COMPOSITION_PIXEL_FORMAT),)
+ LOCAL_CFLAGS += -DCOMPOSITION_PIXEL_FORMAT=$(SF_COMPOSITION_PIXEL_FORMAT)
+endif
diff --git a/current.txt b/current.txt
index 35143af..6bdb1c9 100644
--- a/current.txt
+++ b/current.txt
@@ -391,4 +391,5 @@
1a5ae9793223658174258b523763c557abad6fb917df0b8e3cc097fc89035811 android.hardware.neuralnetworks@1.0::types
4310eb8272f085914952f3bfb73a8f8bb477a80e8b93596f0ea5acb58546b66d android.hardware.neuralnetworks@1.1::types
1d4a5776614c08b5d794a5ec5ab04697260cbd4b3441d5935cd53ee71d19da02 android.hardware.radio@1.0::IRadioResponse
+271187e261b30c01a33011aea257c07a2d2f05b72943ebee89e973e997849973 android.hardware.radio@1.0::types
1d19720d4fd38b1095f0f555a4bd92b3b12c9b1d0f560b0e9a474cd6dcc20db6 android.hardware.radio@1.2::IRadio
diff --git a/graphics/composer/2.1/utils/vts/ComposerVts.cpp b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
index 43a5378..1cafafe 100644
--- a/graphics/composer/2.1/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
@@ -293,7 +293,6 @@
if (queueChanged) {
auto ret = mClient->setInputCommandQueue(*writer->getMQDescriptor());
ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
- return;
}
mClient->executeCommands(commandLength, commandHandles,
diff --git a/graphics/composer/2.1/utils/vts/TestCommandReader.cpp b/graphics/composer/2.1/utils/vts/TestCommandReader.cpp
index e1dc5b6..454a89c 100644
--- a/graphics/composer/2.1/utils/vts/TestCommandReader.cpp
+++ b/graphics/composer/2.1/utils/vts/TestCommandReader.cpp
@@ -26,6 +26,7 @@
namespace vts {
void TestCommandReader::parse() {
+ mErrors.clear();
mCompositionChanges.clear();
while (!isEmpty()) {
IComposerClient::Command command;
@@ -41,7 +42,8 @@
ASSERT_EQ(2, length);
auto loc = read();
auto err = readSigned();
- GTEST_FAIL() << "unexpected error " << err << " at location " << loc;
+ std::pair<uint32_t, uint32_t> error(loc, err);
+ mErrors.push_back(error);
} break;
case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
ASSERT_EQ(0, length % 3);
diff --git a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/TestCommandReader.h b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/TestCommandReader.h
index b9a4a5c..c12debe 100644
--- a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/TestCommandReader.h
+++ b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/TestCommandReader.h
@@ -33,6 +33,7 @@
// unexpected errors or commands.
void parse();
+ std::vector<std::pair<uint32_t, uint32_t>> mErrors;
std::vector<std::pair<uint64_t, uint32_t>> mCompositionChanges;
};
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index 0607d4d..8b8c7ae 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -672,7 +672,10 @@
mReader = std::make_unique<TestCommandReader>();
}
- void TearDown() override { ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); }
+ void TearDown() override {
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
+ }
const native_handle_t* allocate() {
IMapper::BufferDescriptorInfo info{};
diff --git a/graphics/composer/2.2/utils/vts/ComposerVts.cpp b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
index 459e0fe..d8fb656 100644
--- a/graphics/composer/2.2/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
@@ -68,7 +68,6 @@
if (queueChanged) {
auto ret = mClient->setInputCommandQueue(*writer->getMQDescriptor());
ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
- return;
}
mClient->executeCommands(commandLength, commandHandles,
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index fc32951..91318bc 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -119,10 +119,10 @@
// assume the first display is primary and is never removed
mPrimaryDisplay = waitForFirstDisplay();
Config activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay);
- width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
- IComposerClient::Attribute::WIDTH);
- height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
- IComposerClient::Attribute::HEIGHT);
+ mDisplayWidth = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+ IComposerClient::Attribute::WIDTH);
+ mDisplayHeight = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+ IComposerClient::Attribute::HEIGHT);
// explicitly disable vsync
mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
@@ -132,6 +132,11 @@
mWriter = std::make_shared<CommandWriterBase>(1024);
mReader = std::make_unique<TestCommandReader>();
mGralloc = std::make_unique<Gralloc>();
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay, [&](const auto& tmpError, const auto&, const auto&) {
+ mHasReadbackBuffer = tmpError == Error::NONE;
+ });
}
~GraphicsComposerReadbackTest() override {
@@ -166,7 +171,7 @@
}
bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
- const Error& error) {
+ const Error error) {
if (error == Error::UNSUPPORTED) {
return false;
}
@@ -181,19 +186,12 @@
}
void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
- Dataspace* outDataspace, Error* outError) {
+ Dataspace* outDataspace) {
mComposerClient->getRaw()->getReadbackBufferAttributes(
- display,
- [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
- *outError = tmpError;
+ display, [&](const auto&, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
*outPixelFormat = tmpOutPixelFormat;
*outDataspace = tmpOutDataspace;
});
-
- // Not all devices support readback. Pass test if this is the case
- if (!readbackSupported(*outPixelFormat, *outDataspace, *outError)) {
- GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
- }
}
void checkReadbackBuffer(IMapper::BufferDescriptorInfo info, uint32_t stride, void* bufferData,
@@ -202,9 +200,9 @@
ASSERT_NE(-1, bytesPerPixel)
<< "unexpected pixel format " << static_cast<int32_t>(info.format)
<< "(expected RGBA_8888 or RGB_888)";
- for (int row = 0; row < height; row++) {
- for (int col = 0; col < width; col++) {
- int pixel = row * width + col;
+ for (int row = 0; row < mDisplayHeight; row++) {
+ for (int col = 0; col < mDisplayWidth; col++) {
+ int pixel = row * mDisplayWidth + col;
int offset = (row * stride + col) * bytesPerPixel;
uint8_t* pixelColor = (uint8_t*)bufferData + offset;
@@ -221,12 +219,14 @@
sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
// the first display and is assumed never to be removed
Display mPrimaryDisplay;
- int32_t width;
- int32_t height;
+ int32_t mDisplayWidth;
+ int32_t mDisplayHeight;
std::shared_ptr<CommandWriterBase> mWriter;
std::unique_ptr<TestCommandReader> mReader;
std::unique_ptr<Gralloc> mGralloc;
+ bool mHasReadbackBuffer;
+
private:
Display waitForFirstDisplay() {
while (true) {
@@ -241,6 +241,10 @@
};
TEST_F(GraphicsComposerReadbackTest, SingleSolidColorLayer) {
+ if (!mHasReadbackBuffer) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
mWriter->selectDisplay(mPrimaryDisplay);
mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON);
mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB, RenderIntent::COLORIMETRIC);
@@ -255,10 +259,10 @@
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
// expected color for each pixel
- std::vector<IComposerClient::Color> expectedColors(width * height);
- for (int row = 0; row < height; row++) {
- for (int col = 0; col < width; col++) {
- int pixel = row * width + col;
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+ for (int row = 0; row < mDisplayHeight; row++) {
+ for (int col = 0; col < mDisplayWidth; col++) {
+ int pixel = row * mDisplayWidth + col;
if (row >= coloredSquare.top && row < coloredSquare.bottom &&
col >= coloredSquare.left && col < coloredSquare.right) {
expectedColors[pixel] = color;
@@ -270,12 +274,12 @@
PixelFormat pixelFormat;
Dataspace dataspace;
- Error error;
- getReadbackBufferAttributes(mPrimaryDisplay, &pixelFormat, &dataspace, &error);
+
+ getReadbackBufferAttributes(mPrimaryDisplay, &pixelFormat, &dataspace);
IMapper::BufferDescriptorInfo info;
- info.width = width;
- info.height = height;
+ info.width = mDisplayWidth;
+ info.height = mDisplayHeight;
info.layerCount = 1;
info.format = pixelFormat;
info.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
@@ -289,8 +293,6 @@
int32_t fenceHandle;
mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle);
- base::unique_fd fence(fenceHandle);
-
// lock buffer
// Create Rect accessRegion to specify reading the entire buffer
IMapper::Rect accessRegion;
@@ -299,8 +301,17 @@
accessRegion.width = info.width;
accessRegion.height = info.height;
- void* bufData = mGralloc->lock(buffer, info.usage, accessRegion, fence);
+ void* bufData = mGralloc->lock(buffer, info.usage, accessRegion, fenceHandle);
checkReadbackBuffer(info, stride, bufData, expectedColors);
+ int unlockFence = mGralloc->unlock(buffer);
+
+ if (unlockFence != -1) {
+ close(unlockFence);
+ }
+
+ mWriter->validateDisplay();
+ mWriter->presentDisplay();
+ execute();
}
} // anonymous namespace
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index e40dc22..7834b94 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -73,14 +73,29 @@
// assume the first display is primary and is never removed
mPrimaryDisplay = waitForFirstDisplay();
+ Config config = mComposerClient->getActiveConfig(mPrimaryDisplay);
+ mDisplayWidth = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+ IComposerClient::Attribute::WIDTH);
+ mDisplayHeight = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+ IComposerClient::Attribute::HEIGHT);
+
// explicitly disable vsync
mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
mComposerCallback->setVsyncAllowed(false);
mComposerClient->getRaw()->getReadbackBufferAttributes(
- mPrimaryDisplay, [&](const auto& tmpError, const auto&, const auto&) {
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
mHasReadbackBuffer = tmpError == Error::NONE;
+ if (mHasReadbackBuffer) {
+ mReadbackPixelFormat = tmpPixelFormat;
+ mReadbackDataspace = tmpDataspace;
+ ASSERT_LT(static_cast<PixelFormat>(0), mReadbackPixelFormat);
+ ASSERT_NE(Dataspace::UNKNOWN, mReadbackDataspace);
+ }
});
+
+ mInvalidDisplayId = GetInvalidDisplayId();
}
void TearDown() override {
@@ -91,6 +106,22 @@
}
}
+ // returns an invalid display id (one that has not been registered to a
+ // display. Currently assuming that a device will never have close to
+ // std::numeric_limit<uint64_t>::max() displays registered while running tests
+ Display GetInvalidDisplayId() {
+ std::vector<Display> validDisplays = mComposerCallback->getDisplays();
+ uint64_t id = std::numeric_limits<uint64_t>::max();
+ while (id > 0) {
+ if (std::find(validDisplays.begin(), validDisplays.end(), id) == validDisplays.end()) {
+ return id;
+ }
+ id--;
+ }
+
+ return 0;
+ }
+
// use the slot count usually set by SF
static constexpr uint32_t kBufferSlotCount = 64;
@@ -99,8 +130,15 @@
sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
// the first display and is assumed never to be removed
Display mPrimaryDisplay;
+ int32_t mDisplayWidth;
+ int32_t mDisplayHeight;
+
bool mHasReadbackBuffer;
+ uint64_t mInvalidDisplayId;
+ PixelFormat mReadbackPixelFormat;
+ Dataspace mReadbackDataspace;
+
private:
Display waitForFirstDisplay() {
while (true) {
@@ -127,7 +165,10 @@
mReader = std::make_unique<V2_1::vts::TestCommandReader>();
}
- void TearDown() override { ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); }
+ void TearDown() override {
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
+ }
const native_handle_t* allocate() {
IMapper::BufferDescriptorInfo info{};
@@ -189,6 +230,16 @@
{IComposerClient::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
mWriter->setLayerPerFrameMetadata(hidlMetadata);
execute();
+
+ if (mReader->mErrors.size() == 1 &&
+ static_cast<Error>(mReader->mErrors[0].second) == Error::UNSUPPORTED) {
+ mReader->mErrors.clear();
+ GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(mPrimaryDisplay, layer));
+ return;
+ }
+
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(mPrimaryDisplay, layer));
}
/**
@@ -247,9 +298,35 @@
}
/**
+ * Test IComposerClient::getClientTargetSupport_2_2
+ *
+ * Test that IComposerClient::getClientTargetSupport_2_2 returns
+ * Error::BAD_DISPLAY when passed in an invalid display handle
+ */
+
+TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_2BadDisplay) {
+ std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
+ for (auto config : configs) {
+ int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+ IComposerClient::Attribute::WIDTH);
+ int32_t height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+ IComposerClient::Attribute::HEIGHT);
+ ASSERT_LT(0, width);
+ ASSERT_LT(0, height);
+
+ mComposerClient->setActiveConfig(mPrimaryDisplay, config);
+
+ Error error = mComposerClient->getRaw()->getClientTargetSupport_2_2(
+ mInvalidDisplayId, width, height, PixelFormat::RGBA_8888, Dataspace::UNKNOWN);
+
+ EXPECT_EQ(Error::BAD_DISPLAY, error);
+ }
+}
+
+/**
* Test IComposerClient::setPowerMode_2_2.
*/
-TEST_F(GraphicsComposerHidlTest, setPowerMode_2_2) {
+TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2) {
std::vector<IComposerClient::PowerMode> modes;
modes.push_back(IComposerClient::PowerMode::OFF);
modes.push_back(IComposerClient::PowerMode::ON_SUSPEND);
@@ -260,25 +337,118 @@
}
}
-TEST_F(GraphicsComposerHidlTest, setReadbackBuffer) {
+/**
+ * Test IComposerClient::setPowerMode_2_2
+ *
+ * Test that IComposerClient::setPowerMode_2_2 succeeds for different varations
+ * of PowerMode
+ */
+TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2Variations) {
+ std::vector<IComposerClient::PowerMode> modes;
+
+ modes.push_back(IComposerClient::PowerMode::OFF);
+ modes.push_back(IComposerClient::PowerMode::OFF);
+
+ for (auto mode : modes) {
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode));
+ }
+
+ modes.clear();
+
+ modes.push_back(IComposerClient::PowerMode::ON);
+ modes.push_back(IComposerClient::PowerMode::ON);
+
+ for (auto mode : modes) {
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode));
+ }
+
+ modes.clear();
+
+ modes.push_back(IComposerClient::PowerMode::ON_SUSPEND);
+ modes.push_back(IComposerClient::PowerMode::ON_SUSPEND);
+
+ for (auto mode : modes) {
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode));
+ }
+
+ if (mComposerClient->getDozeSupport(mPrimaryDisplay)) {
+ modes.clear();
+
+ modes.push_back(IComposerClient::PowerMode::DOZE);
+ modes.push_back(IComposerClient::PowerMode::DOZE);
+
+ for (auto mode : modes) {
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode));
+ }
+
+ modes.clear();
+
+ modes.push_back(IComposerClient::PowerMode::DOZE_SUSPEND);
+ modes.push_back(IComposerClient::PowerMode::DOZE_SUSPEND);
+
+ for (auto mode : modes) {
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode));
+ }
+ }
+}
+
+/**
+ * Test IComposerClient::setPowerMode_2_2
+ *
+ * Tests that IComposerClient::setPowerMode_2_2 returns BAD_DISPLAY when passed an
+ * invalid display handle
+ */
+TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2BadDisplay) {
+ Error error = mComposerClient->getRaw()->setPowerMode_2_2(mInvalidDisplayId,
+ IComposerClient::PowerMode::ON);
+ ASSERT_EQ(Error::BAD_DISPLAY, error);
+}
+
+/**
+ * Test IComposerClient::setPowerMode_2_2
+ *
+ * Test that IComposerClient::setPowerMode_2_2 returns BAD_PARAMETER when passed
+ * an invalid PowerMode
+ */
+TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2BadParameter) {
+ Error error = mComposerClient->getRaw()->setPowerMode_2_2(
+ mPrimaryDisplay, static_cast<IComposerClient::PowerMode>(-1));
+ ASSERT_EQ(Error::BAD_PARAMETER, error);
+}
+
+/**
+ * Test IComposerClient::setPowerMode_2_2
+ *
+ * Test that IComposerClient::setPowerMode_2_2 returns UNSUPPORTED when passed
+ * DOZE or DOZE_SUPPORT on a device that does not support these modes
+ */
+TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2Unsupported) {
+ if (!mComposerClient->getDozeSupport(mPrimaryDisplay)) {
+ Error error = mComposerClient->getRaw()->setPowerMode_2_2(mPrimaryDisplay,
+ IComposerClient::PowerMode::DOZE);
+ EXPECT_EQ(Error::UNSUPPORTED, error);
+
+ error = mComposerClient->getRaw()->setPowerMode_2_2(
+ mPrimaryDisplay, IComposerClient::PowerMode::DOZE_SUSPEND);
+ EXPECT_EQ(Error::UNSUPPORTED, error);
+ }
+}
+
+/**
+ * Test IComposerClient::setReadbackBuffer
+ *
+ * Test IComposerClient::setReadbackBuffer
+ */
+TEST_F(GraphicsComposerHidlTest, SetReadbackBuffer) {
if (!mHasReadbackBuffer) {
return;
}
- PixelFormat pixelFormat;
- Dataspace dataspace;
- mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &pixelFormat, &dataspace);
- ASSERT_LT(static_cast<PixelFormat>(0), pixelFormat);
- ASSERT_NE(Dataspace::UNKNOWN, dataspace);
-
IMapper::BufferDescriptorInfo info{};
- Config config = mComposerClient->getActiveConfig(mPrimaryDisplay);
- info.width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
- IComposerClient::Attribute::WIDTH);
- info.height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
- IComposerClient::Attribute::HEIGHT);
+ info.width = mDisplayWidth;
+ info.height = mDisplayHeight;
info.layerCount = 1;
- info.format = static_cast<common::V1_0::PixelFormat>(pixelFormat);
+ info.format = static_cast<common::V1_0::PixelFormat>(mReadbackPixelFormat);
// BufferUsage::COMPOSER_OUTPUT is missing
info.usage = static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY | BufferUsage::CPU_READ_OFTEN);
@@ -290,7 +460,49 @@
mComposerClient->setReadbackBuffer(mPrimaryDisplay, buffer, -1);
}
-TEST_F(GraphicsComposerHidlTest, getReadbackBufferFenceInactive) {
+/**
+ * Test IComposerClient::setReadbackBuffer
+ *
+ * Test that IComposerClient::setReadbackBuffer returns an Error::BAD_DISPLAY
+ * when passed an invalid display handle
+ */
+TEST_F(GraphicsComposerHidlTest, SetReadbackBufferBadDisplay) {
+ if (!mHasReadbackBuffer) {
+ return;
+ }
+
+ IMapper::BufferDescriptorInfo info{};
+ info.width = mDisplayWidth;
+ info.height = mDisplayHeight;
+ info.layerCount = 1;
+ info.format = static_cast<common::V1_0::PixelFormat>(mReadbackPixelFormat);
+ info.usage = static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY | BufferUsage::CPU_READ_OFTEN);
+
+ std::unique_ptr<Gralloc> gralloc;
+ const native_handle_t* buffer;
+ ASSERT_NO_FATAL_FAILURE(gralloc = std::make_unique<Gralloc>());
+ ASSERT_NO_FATAL_FAILURE(buffer = gralloc->allocate(info));
+
+ Error error = mComposerClient->getRaw()->setReadbackBuffer(mInvalidDisplayId, buffer, nullptr);
+ ASSERT_EQ(Error::BAD_DISPLAY, error);
+}
+
+/**
+ * Test IComposerClient::setReadbackBuffer
+ *
+ * Test that IComposerClient::setReadbackBuffer returns Error::BAD_PARAMETER
+ * when passed an invalid buffer handle
+ */
+TEST_F(GraphicsComposerHidlTest, SetReadbackBufferBadParameter) {
+ if (!mHasReadbackBuffer) {
+ return;
+ }
+
+ Error error = mComposerClient->getRaw()->setReadbackBuffer(mPrimaryDisplay, nullptr, nullptr);
+ ASSERT_EQ(Error::BAD_PARAMETER, error);
+}
+
+TEST_F(GraphicsComposerHidlTest, GetReadbackBufferFenceInactive) {
if (!mHasReadbackBuffer) {
return;
}
@@ -311,14 +523,38 @@
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->selectLayer(layer);
+ mWriter->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
mWriter->setLayerFloatColor(IComposerClient::FloatColor{1.0, 1.0, 1.0, 1.0});
mWriter->setLayerFloatColor(IComposerClient::FloatColor{0.0, 0.0, 0.0, 0.0});
+ execute();
+
+ if (mReader->mErrors.size() == 2 &&
+ static_cast<Error>(mReader->mErrors[0].second) == Error::UNSUPPORTED &&
+ static_cast<Error>(mReader->mErrors[1].second) == Error::UNSUPPORTED) {
+ mReader->mErrors.clear();
+ GTEST_SUCCEED() << "SetLayerFloatColor is not supported";
+ return;
+ }
+
+ // ensure setting float color on layer with composition type that is not
+ // SOLID_COLOR does not fail
+ V2_1::Layer clientLayer;
+ ASSERT_NO_FATAL_FAILURE(clientLayer =
+ mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(clientLayer);
+ mWriter->setLayerCompositionType(IComposerClient::Composition::CLIENT);
+ mWriter->setLayerFloatColor(IComposerClient::FloatColor{1.0, 1.0, 1.0, 1.0});
+ execute();
+
+ // At this point we know that this function is supported so there should be
+ // no errors (checked upon TearDown)
}
/**
* Test IComposerClient::getDataspaceSaturationMatrix.
*/
-TEST_F(GraphicsComposerHidlTest, getDataspaceSaturationMatrix) {
+TEST_F(GraphicsComposerHidlTest, GetDataspaceSaturationMatrix) {
auto matrix = mComposerClient->getDataspaceSaturationMatrix(Dataspace::SRGB_LINEAR);
// the last row is known
ASSERT_EQ(0.0f, matrix[12]);
@@ -327,6 +563,19 @@
ASSERT_EQ(1.0f, matrix[15]);
}
+/*
+ * Test IComposerClient::getDataspaceSaturationMatrix
+ *
+ * Test that IComposerClient::getDataspaceSaturationMatrix returns
+ * Error::BAD_PARAMETER when passed a dataspace other than
+ * Dataspace::SRGB_LINEAR
+ */
+TEST_F(GraphicsComposerHidlTest, GetDataspaceSaturationMatrixBadParameter) {
+ mComposerClient->getRaw()->getDataspaceSaturationMatrix(
+ Dataspace::UNKNOWN,
+ [&](const auto& tmpError, const auto&) { ASSERT_EQ(Error::BAD_PARAMETER, tmpError); });
+}
+
/**
* Test IComposerClient::getColorMode_2_2.
*/
@@ -337,10 +586,22 @@
EXPECT_NE(modes.cend(), nativeMode);
}
-/**
- * Test IComposerClient::getRenderIntent.
+/*
+ * Test IComposerClient::getColorMode_2_2
+ *
+ * Test that IComposerClient::getColorMode returns Error::BAD_DISPLAY when
+ * passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntent) {
+TEST_F(GraphicsComposerHidlTest, GetColorMode_2_2BadDisplay) {
+ mComposerClient->getRaw()->getColorModes_2_2(
+ mInvalidDisplayId,
+ [&](const auto& tmpError, const auto&) { ASSERT_EQ(Error::BAD_DISPLAY, tmpError); });
+}
+
+/**
+ * Test IComposerClient::getRenderIntents.
+ */
+TEST_F(GraphicsComposerHidlTest, GetRenderIntents) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
for (auto mode : modes) {
std::vector<RenderIntent> intents =
@@ -364,6 +625,33 @@
}
}
+/*
+ * Test IComposerClient::getRenderIntents
+ *
+ * Test that IComposerClient::getRenderIntent returns Error::BAD_DISPLAY when
+ * passed an invalid display handle
+ */
+TEST_F(GraphicsComposerHidlTest, GetRenderIntentsBadDisplay) {
+ std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
+ for (auto mode : modes) {
+ mComposerClient->getRaw()->getRenderIntents(
+ mInvalidDisplayId, mode,
+ [&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_DISPLAY, tmpError); });
+ }
+}
+
+/*
+ * Test IComposerClient::getRenderIntents
+ *
+ * Test that IComposerClient::getRenderIntents returns Error::BAD_PARAMETER when
+ * pased either an invalid Color mode or an invalid Render Intent
+ */
+TEST_F(GraphicsComposerHidlTest, GetRenderIntentsBadParameter) {
+ mComposerClient->getRaw()->getRenderIntents(
+ mPrimaryDisplay, static_cast<ColorMode>(-1),
+ [&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_PARAMETER, tmpError); });
+}
+
/**
* Test IComposerClient::setColorMode_2_2.
*/
@@ -376,6 +664,37 @@
mComposerClient->setColorMode(mPrimaryDisplay, mode, intent);
}
}
+
+ mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE, RenderIntent::COLORIMETRIC);
+}
+
+/*
+ * Test IComposerClient::setColorMode_2_2
+ *
+ * Test that IComposerClient::setColorMode_2_2 returns an Error::BAD_DISPLAY
+ * when passed an invalid display handle
+ */
+TEST_F(GraphicsComposerHidlTest, SetColorMode_2_2BadDisplay) {
+ Error error = mComposerClient->getRaw()->setColorMode_2_2(mInvalidDisplayId, ColorMode::NATIVE,
+ RenderIntent::COLORIMETRIC);
+
+ ASSERT_EQ(Error::BAD_DISPLAY, error);
+}
+
+/*
+ * Test IComposerClient::setColorMode_2_2
+ *
+ * Test that IComposerClient::setColorMode_2_2 returns Error::BAD_PARAMETER when
+ * passed an invalid Color mode or an invalid render intent
+ */
+TEST_F(GraphicsComposerHidlTest, SetColorMode_2_2BadParameter) {
+ Error colorModeError = mComposerClient->getRaw()->setColorMode_2_2(
+ mPrimaryDisplay, static_cast<ColorMode>(-1), RenderIntent::COLORIMETRIC);
+ EXPECT_EQ(Error::BAD_PARAMETER, colorModeError);
+
+ Error renderIntentError = mComposerClient->getRaw()->setColorMode_2_2(
+ mPrimaryDisplay, ColorMode::NATIVE, static_cast<RenderIntent>(-1));
+ EXPECT_EQ(Error::BAD_PARAMETER, renderIntentError);
}
} // namespace
diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
index c89abd9..6ed61da 100644
--- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
+++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
@@ -651,6 +651,8 @@
return {3072, 4096};
case Algorithm::EC:
return {224, 384, 521};
+ case Algorithm::AES:
+ return {192};
default:
return {};
}
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index 3919a69..784ae30 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -751,6 +751,7 @@
* presented.
*/
TEST_F(SigningOperationsTest, NoUserConfirmation) {
+ if (SecLevel() == SecurityLevel::STRONGBOX) return;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 65537)
.Digest(Digest::NONE)
@@ -773,7 +774,7 @@
*/
TEST_F(SigningOperationsTest, RsaPkcs1Sha256Success) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::SHA_2_256)
.Authorization(TAG_NO_AUTH_REQUIRED)
.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)));
@@ -790,7 +791,7 @@
*/
TEST_F(SigningOperationsTest, RsaPkcs1NoDigestSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Authorization(TAG_NO_AUTH_REQUIRED)
.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)));
@@ -808,11 +809,11 @@
*/
TEST_F(SigningOperationsTest, RsaPkcs1NoDigestTooLong) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Authorization(TAG_NO_AUTH_REQUIRED)
.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)));
- string message(129, 'a');
+ string message(257, 'a');
EXPECT_EQ(ErrorCode::OK,
Begin(KeyPurpose::SIGN, AuthorizationSetBuilder()
@@ -855,12 +856,12 @@
*/
TEST_F(SigningOperationsTest, RsaNoPaddingTooLong) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Authorization(TAG_NO_AUTH_REQUIRED)
.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)));
// One byte too long
- string message(1024 / 8 + 1, 'a');
+ string message(2048 / 8 + 1, 'a');
ASSERT_EQ(ErrorCode::OK,
Begin(KeyPurpose::SIGN, AuthorizationSetBuilder()
.Digest(Digest::NONE)
@@ -889,7 +890,7 @@
*/
TEST_F(SigningOperationsTest, RsaAbort) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Authorization(TAG_NO_AUTH_REQUIRED)
.Padding(PaddingMode::NONE)));
@@ -914,7 +915,7 @@
*/
TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Authorization(TAG_NO_AUTH_REQUIRED)
.Digest(Digest::SHA_2_256 /* supported digest */)
.Padding(PaddingMode::PKCS7)));
@@ -931,7 +932,7 @@
*/
TEST_F(SigningOperationsTest, RsaNoDigest) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Authorization(TAG_NO_AUTH_REQUIRED)
.Digest(Digest::NONE)
.Padding(PaddingMode::RSA_PSS)));
@@ -952,7 +953,7 @@
TEST_F(SigningOperationsTest, RsaNoPadding) {
// Padding must be specified
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaKey(1024, 65537)
+ .RsaKey(2048, 65537)
.Authorization(TAG_NO_AUTH_REQUIRED)
.SigningKey()
.Digest(Digest::NONE)));
@@ -968,12 +969,12 @@
TEST_F(SigningOperationsTest, RsaTooShortMessage) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)));
// Barely shorter
- string message(1024 / 8 - 1, 'a');
+ string message(2048 / 8 - 1, 'a');
SignMessage(message, AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE));
// Much shorter
@@ -989,7 +990,7 @@
TEST_F(SigningOperationsTest, RsaSignWithEncryptionKey) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaEncryptionKey(1024, 65537)
+ .RsaEncryptionKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)));
ASSERT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE,
@@ -1006,12 +1007,12 @@
TEST_F(SigningOperationsTest, RsaSignTooLargeMessage) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)));
// Largest possible message will always be larger than the public modulus.
- string message(1024 / 8, static_cast<char>(0xff));
+ string message(2048 / 8, static_cast<char>(0xff));
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.Digest(Digest::NONE)
@@ -1328,7 +1329,7 @@
TEST_F(VerificationOperationsTest, RsaSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)));
string message = "12345678901234567890123456789012";
@@ -1567,7 +1568,7 @@
*/
TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)));
HidlBuf export_data;
@@ -1583,7 +1584,7 @@
TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)));
for (size_t i = 0; i < key_blob_.size(); ++i) {
@@ -1975,16 +1976,16 @@
TEST_F(EncryptionOperationsTest, RsaNoPaddingSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaEncryptionKey(1024, 65537)
+ .RsaEncryptionKey(2048, 65537)
.Padding(PaddingMode::NONE)));
- string message = string(1024 / 8, 'a');
+ string message = string(2048 / 8, 'a');
auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE);
string ciphertext1 = EncryptMessage(message, params);
- EXPECT_EQ(1024U / 8, ciphertext1.size());
+ EXPECT_EQ(2048U / 8, ciphertext1.size());
string ciphertext2 = EncryptMessage(message, params);
- EXPECT_EQ(1024U / 8, ciphertext2.size());
+ EXPECT_EQ(2048U / 8, ciphertext2.size());
// Unpadded RSA is deterministic
EXPECT_EQ(ciphertext1, ciphertext2);
@@ -1998,16 +1999,16 @@
TEST_F(EncryptionOperationsTest, RsaNoPaddingShortMessage) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaEncryptionKey(1024, 65537)
+ .RsaEncryptionKey(2048, 65537)
.Padding(PaddingMode::NONE)));
string message = "1";
auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE);
string ciphertext = EncryptMessage(message, params);
- EXPECT_EQ(1024U / 8, ciphertext.size());
+ EXPECT_EQ(2048U / 8, ciphertext.size());
- string expected_plaintext = string(1024 / 8 - 1, 0) + message;
+ string expected_plaintext = string(2048U / 8 - 1, 0) + message;
string plaintext = DecryptMessage(ciphertext, params);
EXPECT_EQ(expected_plaintext, plaintext);
@@ -2015,8 +2016,8 @@
// Degenerate case, encrypting a numeric 1 yields 0x00..01 as the ciphertext.
message = static_cast<char>(1);
ciphertext = EncryptMessage(message, params);
- EXPECT_EQ(1024U / 8, ciphertext.size());
- EXPECT_EQ(ciphertext, string(1024 / 8 - 1, 0) + message);
+ EXPECT_EQ(2048U / 8, ciphertext.size());
+ EXPECT_EQ(ciphertext, string(2048U / 8 - 1, 0) + message);
}
/*
@@ -2027,10 +2028,10 @@
TEST_F(EncryptionOperationsTest, RsaNoPaddingTooLong) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaEncryptionKey(1024, 65537)
+ .RsaEncryptionKey(2048, 65537)
.Padding(PaddingMode::NONE)));
- string message(1024 / 8 + 1, 'a');
+ string message(2048 / 8 + 1, 'a');
auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE);
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
@@ -2047,7 +2048,7 @@
TEST_F(EncryptionOperationsTest, RsaNoPaddingTooLarge) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaEncryptionKey(1024, 65537)
+ .RsaEncryptionKey(2048, 65537)
.Padding(PaddingMode::NONE)));
HidlBuf exported;
@@ -2058,7 +2059,7 @@
RSA_Ptr rsa(EVP_PKEY_get1_RSA(pkey.get()));
size_t modulus_len = BN_num_bytes(rsa->n);
- ASSERT_EQ(1024U / 8, modulus_len);
+ ASSERT_EQ(2048U / 8, modulus_len);
std::unique_ptr<uint8_t[]> modulus_buf(new uint8_t[modulus_len]);
BN_bn2bin(rsa->n, modulus_buf.get());
@@ -2074,7 +2075,7 @@
// One smaller than the modulus is okay.
BN_sub(rsa->n, rsa->n, BN_value_one());
modulus_len = BN_num_bytes(rsa->n);
- ASSERT_EQ(1024U / 8, modulus_len);
+ ASSERT_EQ(2048U / 8, modulus_len);
BN_bn2bin(rsa->n, modulus_buf.get());
message = string(reinterpret_cast<const char*>(modulus_buf.get()), modulus_len);
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
@@ -2140,7 +2141,7 @@
TEST_F(EncryptionOperationsTest, RsaOaepInvalidDigest) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaEncryptionKey(1024, 65537)
+ .RsaEncryptionKey(2048, 65537)
.Padding(PaddingMode::RSA_OAEP)
.Digest(Digest::NONE)));
string message = "Hello World!";
@@ -2186,12 +2187,12 @@
TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaEncryptionKey(1024, 65537)
+ .RsaEncryptionKey(2048, 65537)
.Padding(PaddingMode::RSA_OAEP)
.Digest(Digest::SHA_2_256)));
constexpr size_t digest_size = 256 /* SHA_2_256 */ / 8;
constexpr size_t oaep_overhead = 2 * digest_size + 2;
- string message(1024 / 8 - oaep_overhead + 1, 'a');
+ string message(2048 / 8 - oaep_overhead + 1, 'a');
EXPECT_EQ(ErrorCode::OK,
Begin(KeyPurpose::ENCRYPT,
AuthorizationSetBuilder().Padding(PaddingMode::RSA_OAEP).Digest(Digest::SHA_2_256)));
@@ -2208,16 +2209,16 @@
TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaEncryptionKey(1024, 65537)
+ .RsaEncryptionKey(2048, 65537)
.Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)));
string message = "Hello World!";
auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT);
string ciphertext1 = EncryptMessage(message, params);
- EXPECT_EQ(1024U / 8, ciphertext1.size());
+ EXPECT_EQ(2048U / 8, ciphertext1.size());
string ciphertext2 = EncryptMessage(message, params);
- EXPECT_EQ(1024U / 8, ciphertext2.size());
+ EXPECT_EQ(2048U / 8, ciphertext2.size());
// PKCS1 v1.5 randomizes padding so every result should be different.
EXPECT_NE(ciphertext1, ciphertext2);
@@ -2247,9 +2248,9 @@
TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaEncryptionKey(1024, 65537)
+ .RsaEncryptionKey(2048, 65537)
.Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)));
- string message(1024 / 8 - 10, 'a');
+ string message(2048 / 8 - 10, 'a');
auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT);
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
@@ -2632,9 +2633,13 @@
* Verifies AES CTR implementation against SP800-38A test vectors.
*/
TEST_F(EncryptionOperationsTest, AesCtrSp80038aTestVector) {
+ std::vector<uint32_t> InvalidSizes = InvalidKeySizes(Algorithm::AES);
for (size_t i = 0; i < 3; i++) {
const AesCtrSp80038aTestVector& test(kAesCtrSp80038aTestVectors[i]);
const string key = hex2str(test.key);
+ if (std::find(InvalidSizes.begin(), InvalidSizes.end(), (key.size() * 8)) !=
+ InvalidSizes.end())
+ continue;
const string nonce = hex2str(test.nonce);
const string plaintext = hex2str(test.plaintext);
const string ciphertext = hex2str(test.ciphertext);
@@ -3827,7 +3832,7 @@
TEST_F(AttestationTest, RsaAttestation) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_INCLUDE_UNIQUE_ID)));
@@ -3854,7 +3859,7 @@
TEST_F(AttestationTest, RsaAttestationRequiresAppId) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_INCLUDE_UNIQUE_ID)));
@@ -3965,7 +3970,7 @@
*/
TEST_F(KeyDeletionTest, DeleteKey) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_NO_AUTH_REQUIRED)));
@@ -4009,7 +4014,7 @@
TEST_F(KeyDeletionTest, DeleteInvalidKey) {
// Generate key just to check if rollback protection is implemented
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_NO_AUTH_REQUIRED)));
@@ -4048,7 +4053,7 @@
TEST_F(KeyDeletionTest, DeleteAllKeys) {
if (!arm_deleteAllKeys) return;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(1024, 65537)
+ .RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_NO_AUTH_REQUIRED)));
diff --git a/media/bufferpool/2.0/IAccessor.hal b/media/bufferpool/2.0/IAccessor.hal
index 07ea99d..bd70945 100644
--- a/media/bufferpool/2.0/IAccessor.hal
+++ b/media/bufferpool/2.0/IAccessor.hal
@@ -59,10 +59,14 @@
* to get shared buffers from the buffer pool.
* @return connectionId Id of IConnection. The Id identifies
* sender and receiver in FMQ messages during buffer transfer.
- * @return mqDesc FMQ descriptor. The descriptor can be used to
- * send/receive FMQ messages.
+ * @return toFmqDesc FMQ descriptor. The descriptor is used to
+ * post buffer status messages.
+ * @return fromFmqDesc FMQ descriptor. The descriptor is used to
+ * receive buffer invalidation messages from the buffer pool.
*/
connect()
generates (ResultStatus status, IConnection connection,
- int64_t connectionId, fmq_sync<BufferStatusMessage> mqDesc);
+ int64_t connectionId,
+ fmq_sync<BufferStatusMessage> toFmqDesc,
+ fmq_sync<BufferInvalidationMessage> fromFmqDesc);
};
diff --git a/media/bufferpool/2.0/types.hal b/media/bufferpool/2.0/types.hal
index d5b3937..7ce53b1 100644
--- a/media/bufferpool/2.0/types.hal
+++ b/media/bufferpool/2.0/types.hal
@@ -91,3 +91,19 @@
*/
int64_t timestampUs;
};
+
+/*
+ * Buffer pool sends a buffer invalidation message to clients in order to
+ * ensure fast reclamation of the buffers. Clients must free the invalidated
+ * buffers as soon as possible upon receiving the message.
+ */
+struct BufferInvalidationMessage {
+ /**
+ * Buffers from fromBufferId to toBufferId must be invalidated.
+ * Both of fromBufferId and toBufferId are inclusive.
+ * If fromBufferId > toBufferID, wrap happens. In that case
+ * the wrap is based on UINT32_MAX.
+ */
+ uint32_t fromBufferId;
+ uint32_t toBufferId;
+};
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index 0682ab9..64495cf 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -66,8 +66,8 @@
// Top level driver for models and examples generated by test_generator.py
// Test driver for those generated from ml/nn/runtime/test/spec
void EvaluatePreparedModel(sp<IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
- const std::vector<MixedTypedExampleType>& examples,
- float fpRange = 1e-5f) {
+ const std::vector<MixedTypedExampleType>& examples, float fpAtol = 1e-5f,
+ float fpRtol = 1e-5f) {
const uint32_t INPUT = 0;
const uint32_t OUTPUT = 1;
@@ -175,7 +175,7 @@
MixedTyped filtered_test = filter(test, is_ignored);
// We want "close-enough" results for float
- compare(filtered_golden, filtered_test, fpRange);
+ compare(filtered_golden, filtered_test, fpAtol, fpRtol);
}
}
@@ -220,7 +220,8 @@
EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
ASSERT_NE(nullptr, preparedModel.get());
- EvaluatePreparedModel(preparedModel, is_ignored, examples);
+ float fpAtol = 1e-5f, fpRtol = 5.0f * 1.1920928955078125e-7f;
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, fpAtol, fpRtol);
}
void Execute(const sp<V1_1::IDevice>& device, std::function<V1_1::Model(void)> create_model,
@@ -265,9 +266,13 @@
EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
ASSERT_NE(nullptr, preparedModel.get());
- // If in relaxed mode, set the error range to be 5ULP of FP16.
- float fpRange = !model.relaxComputationFloat32toFloat16 ? 1e-5f : 5.0f * 0.0009765625f;
- EvaluatePreparedModel(preparedModel, is_ignored, examples, fpRange);
+ // TODO: Adjust the error limit based on testing.
+ // If in relaxed mode, set the absolute tolerance to be 5ULP of FP16.
+ float fpAtol = !model.relaxComputationFloat32toFloat16 ? 1e-5f : 5.0f * 0.0009765625f;
+ // Set the relative tolerance to be 5ULP of the corresponding FP precision.
+ float fpRtol = !model.relaxComputationFloat32toFloat16 ? 5.0f * 1.1920928955078125e-7f
+ : 5.0f * 0.0009765625f;
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, fpAtol, fpRtol);
}
} // namespace generated_tests
diff --git a/radio/1.0/types.hal b/radio/1.0/types.hal
index ab1834b..17718e0 100644
--- a/radio/1.0/types.hal
+++ b/radio/1.0/types.hal
@@ -1500,9 +1500,10 @@
};
struct CellIdentityGsm {
- string mcc; // 3-digit Mobile Country Code, 0..999, INT_MAX if unknown
- string mnc; // 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if
+ string mcc; // 3-digit Mobile Country Code, 0..999, empty string if
// unknown
+ string mnc; // 2 or 3-digit Mobile Network Code, 0..999, empty string
+ // if unknown
int32_t lac; // 16-bit Location Area Code, 0..65535, INT_MAX if unknown
int32_t cid; // 16-bit GSM Cell Identity described in
// TS 27.007, 0..65535, INT_MAX if unknown
@@ -1512,8 +1513,9 @@
};
struct CellIdentityWcdma {
- string mcc; // 3-digit Mobile Country Code, 0..999, INT_MAX if unknown
- string mnc; // 2 or 3-digit Mobile Network Code, 0..999, INT_MAX
+ string mcc; // 3-digit Mobile Country Code, 0..999, empty string if
+ // unknown
+ string mnc; // 2 or 3-digit Mobile Network Code, 0..999, empty string
// if unknown
int32_t lac; // 16-bit Location Area Code, 0..65535, INT_MAX if unknown
int32_t cid; // 28-bit UMTS Cell Identity described in
@@ -1541,9 +1543,10 @@
};
struct CellIdentityLte {
- string mcc; // 3-digit Mobile Country Code, 0..999, INT_MAX if unknown
- string mnc; // 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if
+ string mcc; // 3-digit Mobile Country Code, 0..999, empty string if
// unknown
+ string mnc; // 2 or 3-digit Mobile Network Code, 0..999, empty string
+ // if unknown
int32_t ci; // 28-bit Cell Identity described in TS TS 27.007, INT_MAX
// if unknown
int32_t pci; // physical cell id 0..503; this value must be valid
@@ -1553,9 +1556,10 @@
};
struct CellIdentityTdscdma {
- string mcc; // 3-digit Mobile Country Code, 0..999, INT_MAX if unknown
- string mnc; // 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if
+ string mcc; // 3-digit Mobile Country Code, 0..999, empty string if
// unknown
+ string mnc; // 2 or 3-digit Mobile Network Code, 0..999, empty string
+ // if unknown
int32_t lac; // 16-bit Location Area Code, 0..65535, INT_MAX if
// unknown
int32_t cid; // 28-bit UMTS Cell Identity described in
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
index 4f10f11..eaef3ed 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -32,6 +32,67 @@
if (cardStatus.cardState == CardState::ABSENT) {
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ } else if (cardStatus.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp->rspInfo.error,
+ {RadioError::NONE, RadioError::NOT_PROVISIONED, RadioError::CANCELLED}));
+
+ // Check the mcc [0, 999] and mnc [0, 999].
+ string hidl_mcc;
+ string hidl_mnc;
+ bool checkMccMnc = true;
+ int totalIdentitySizeExpected = 1;
+ CellIdentity cellIdentities = radioRsp->dataRegResp.cellIdentity;
+ CellInfoType cellInfoType = cellIdentities.cellInfoType;
+
+ if (cellInfoType == CellInfoType::NONE) {
+ // All the fields are 0
+ totalIdentitySizeExpected = 0;
+ checkMccMnc = false;
+ } else if (cellInfoType == CellInfoType::GSM) {
+ EXPECT_EQ(1, cellIdentities.cellIdentityGsm.size());
+ CellIdentityGsm cig = cellIdentities.cellIdentityGsm[0];
+ hidl_mcc = cig.mcc;
+ hidl_mnc = cig.mnc;
+ } else if (cellInfoType == CellInfoType::LTE) {
+ EXPECT_EQ(1, cellIdentities.cellIdentityLte.size());
+ CellIdentityLte cil = cellIdentities.cellIdentityLte[0];
+ hidl_mcc = cil.mcc;
+ hidl_mnc = cil.mnc;
+ } else if (cellInfoType == CellInfoType::WCDMA) {
+ EXPECT_EQ(1, cellIdentities.cellIdentityWcdma.size());
+ CellIdentityWcdma ciw = cellIdentities.cellIdentityWcdma[0];
+ hidl_mcc = ciw.mcc;
+ hidl_mnc = ciw.mnc;
+ } else if (cellInfoType == CellInfoType::TD_SCDMA) {
+ EXPECT_EQ(1, cellIdentities.cellIdentityTdscdma.size());
+ CellIdentityTdscdma cit = cellIdentities.cellIdentityTdscdma[0];
+ hidl_mcc = cit.mcc;
+ hidl_mnc = cit.mnc;
+ } else {
+ // CellIndentityCdma has no mcc and mnc.
+ EXPECT_EQ(CellInfoType::CDMA, cellInfoType);
+ EXPECT_EQ(1, cellIdentities.cellIdentityCdma.size());
+ checkMccMnc = false;
+ }
+
+ // Check only one CellIdentity is size 1, and others must be 0.
+ EXPECT_EQ(totalIdentitySizeExpected, cellIdentities.cellIdentityGsm.size() +
+ cellIdentities.cellIdentityCdma.size() +
+ cellIdentities.cellIdentityLte.size() +
+ cellIdentities.cellIdentityWcdma.size() +
+ cellIdentities.cellIdentityTdscdma.size());
+
+ if (checkMccMnc) {
+ // 32 bit system gets result: "\xff\xff\xff..." from RIL, which is not testable. Only
+ // test for 64 bit here. TODO: remove this limit after b/113181277 being fixed.
+ if (hidl_mcc.size() < 4 && hidl_mnc.size() < 4) {
+ int mcc = stoi(hidl_mcc);
+ int mnc = stoi(hidl_mnc);
+ EXPECT_TRUE(mcc >= 0 && mcc <= 999);
+ EXPECT_TRUE(mnc >= 0 && mnc <= 999);
+ }
+ }
}
}
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h b/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
index f5ce072..23bc434 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
+++ b/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
@@ -60,6 +60,9 @@
uint32_t writeSmsToSimIndex;
uint32_t writeSmsToRuimIndex;
+ // Data
+ DataRegStateResult dataRegResp;
+
RadioResponse(RadioHidlTest& parent);
virtual ~RadioResponse() = default;
diff --git a/radio/1.0/vts/functional/radio_response.cpp b/radio/1.0/vts/functional/radio_response.cpp
index 93d5557..f3938a9 100644
--- a/radio/1.0/vts/functional/radio_response.cpp
+++ b/radio/1.0/vts/functional/radio_response.cpp
@@ -157,8 +157,9 @@
}
Return<void> RadioResponse::getDataRegistrationStateResponse(
- const RadioResponseInfo& info, const DataRegStateResult& /*dataRegResponse*/) {
+ const RadioResponseInfo& info, const DataRegStateResult& dataRegResponse) {
rspInfo = info;
+ dataRegResp = dataRegResponse;
parent.notify(info.serial);
return Void();
}
diff --git a/radio/1.0/vts/functional/vts_test_util.cpp b/radio/1.0/vts/functional/vts_test_util.cpp
index 7d15f35..ec96e5f 100644
--- a/radio/1.0/vts/functional/vts_test_util.cpp
+++ b/radio/1.0/vts/functional/vts_test_util.cpp
@@ -53,4 +53,4 @@
}
}
return testing::AssertionFailure() << "SapError:" + toString(err) + " is returned";
-}
+}
\ No newline at end of file
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
index 3510163..730d969 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
@@ -753,6 +753,56 @@
ASSERT_TRUE(CheckAnyOfErrors(
radioRsp_v1_2->rspInfo.error,
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::NOT_PROVISIONED}));
+
+ // Check the mcc [0, 999] and mnc [0, 999].
+ string hidl_mcc;
+ string hidl_mnc;
+ int totalIdentitySizeExpected = 1;
+ ::android::hardware::radio::V1_2::CellIdentity cellIdentities =
+ radioRsp_v1_2->dataRegResp.cellIdentity;
+ CellInfoType cellInfoType = cellIdentities.cellInfoType;
+
+ if (cellInfoType == CellInfoType::NONE) {
+ // All the fields are 0
+ totalIdentitySizeExpected = 0;
+ } else if (cellInfoType == CellInfoType::GSM) {
+ EXPECT_EQ(1, cellIdentities.cellIdentityGsm.size());
+ ::android::hardware::radio::V1_2::CellIdentityGsm cig = cellIdentities.cellIdentityGsm[0];
+ hidl_mcc = cig.base.mcc;
+ hidl_mnc = cig.base.mnc;
+ } else if (cellInfoType == CellInfoType::LTE) {
+ EXPECT_EQ(1, cellIdentities.cellIdentityLte.size());
+ ::android::hardware::radio::V1_2::CellIdentityLte cil = cellIdentities.cellIdentityLte[0];
+ hidl_mcc = cil.base.mcc;
+ hidl_mnc = cil.base.mnc;
+ } else if (cellInfoType == CellInfoType::WCDMA) {
+ EXPECT_EQ(1, cellIdentities.cellIdentityWcdma.size());
+ ::android::hardware::radio::V1_2::CellIdentityWcdma ciw =
+ cellIdentities.cellIdentityWcdma[0];
+ hidl_mcc = ciw.base.mcc;
+ hidl_mnc = ciw.base.mnc;
+ } else if (cellInfoType == CellInfoType::TD_SCDMA) {
+ EXPECT_EQ(1, cellIdentities.cellIdentityTdscdma.size());
+ ::android::hardware::radio::V1_2::CellIdentityTdscdma cit =
+ cellIdentities.cellIdentityTdscdma[0];
+ hidl_mcc = cit.base.mcc;
+ hidl_mnc = cit.base.mnc;
+ } else {
+ // CellIndentityCdma has no mcc and mnc.
+ EXPECT_EQ(CellInfoType::CDMA, cellInfoType);
+ EXPECT_EQ(1, cellIdentities.cellIdentityCdma.size());
+ }
+
+ // Check only one CellIdentity is size 1, and others must be 0.
+ EXPECT_EQ(totalIdentitySizeExpected,
+ cellIdentities.cellIdentityGsm.size() + cellIdentities.cellIdentityCdma.size() +
+ cellIdentities.cellIdentityLte.size() + cellIdentities.cellIdentityWcdma.size() +
+ cellIdentities.cellIdentityTdscdma.size());
+
+ int mcc = stoi(hidl_mcc);
+ int mnc = stoi(hidl_mnc);
+ EXPECT_TRUE(mcc >= 0 && mcc <= 999);
+ EXPECT_TRUE(mnc >= 0 && mnc <= 999);
}
/*
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
index 4712202..2e65bfb 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
+++ b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
@@ -56,6 +56,9 @@
RadioResponseInfo rspInfo;
+ // Data
+ ::android::hardware::radio::V1_2::DataRegStateResult dataRegResp;
+
RadioResponse_v1_2(RadioHidlTest_v1_2& parent_v1_2);
virtual ~RadioResponse_v1_2() = default;
diff --git a/radio/1.2/vts/functional/radio_response.cpp b/radio/1.2/vts/functional/radio_response.cpp
index c5c7b14..e91a557 100644
--- a/radio/1.2/vts/functional/radio_response.cpp
+++ b/radio/1.2/vts/functional/radio_response.cpp
@@ -756,8 +756,9 @@
Return<void> RadioResponse_v1_2::getDataRegistrationStateResponse_1_2(
const RadioResponseInfo& info,
- const ::android::hardware::radio::V1_2::DataRegStateResult& /*dataRegResponse*/) {
+ const ::android::hardware::radio::V1_2::DataRegStateResult& dataRegResponse) {
rspInfo = info;
+ dataRegResp = dataRegResponse;
parent_v1_2.notify(info.serial);
return Void();
}
diff --git a/radio/1.3/Android.bp b/radio/1.3/Android.bp
index 3c7b5c5..042df6c 100644
--- a/radio/1.3/Android.bp
+++ b/radio/1.3/Android.bp
@@ -9,6 +9,8 @@
srcs: [
"types.hal",
"IRadio.hal",
+ "IRadioIndication.hal",
+ "IRadioResponse.hal",
],
interfaces: [
"android.hardware.radio@1.0",
@@ -18,6 +20,8 @@
],
types: [
"AccessNetwork",
+ "EmergencyNumber",
+ "EmergencyServiceCategory",
],
gen_java: true,
}
diff --git a/radio/1.3/IRadio.hal b/radio/1.3/IRadio.hal
index 16e6684..480a61f 100644
--- a/radio/1.3/IRadio.hal
+++ b/radio/1.3/IRadio.hal
@@ -17,9 +17,11 @@
package android.hardware.radio@1.3;
import @1.0::DataProfileInfo;
+import @1.0::Dial;
import @1.2::DataRequestReason;
import @1.2::IRadio;
import @1.3::AccessNetwork;
+import @1.3::EmergencyServiceCategory;
/**
* This interface is used by telephony and telecom to talk to cellular radio.
@@ -82,4 +84,45 @@
oneway setupDataCall_1_3(int32_t serial, AccessNetwork accessNetwork,
DataProfileInfo dataProfileInfo, bool modemCognitive, bool roamingAllowed,
bool isRoaming, DataRequestReason reason, vec<string> addresses, vec<string> dnses);
+
+ /**
+ * Request the current emergency number list.
+ *
+ * Each emergency number (@1.3::EmergencyNumber) in the emergency number list contains a
+ * dialing number, one or more service category(s), and mobile country code.
+ *
+ * Radio must collect all sources of the emergency number to build the response.
+ * For example, network operator signals, sim card information, modem configuration, OEM
+ * configuration (for example, OEM system properties), always-available emergency numbers and
+ * sim-absence emergency numbers, etc.
+ *
+ * 112, 911 are always available. Besides, 000, 08, 110, 999, 118 and 119 should be available
+ * when sim is not present.
+ *
+ * Please refer the document of @1.3::EmergencyNumber to construct each emergency number to be
+ * returned.
+ *
+ * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
+ *
+ * @param serial Serial number of request.
+ *
+ * Response function is IRadioResponse.getCurrentEmergencyNumberListResponse()
+ */
+ oneway getCurrentEmergencyNumberList(int32_t serial);
+
+ /**
+ * Initiate emergency voice call, with one or more emergency service category(s).
+ *
+ * Note this API is the same as IRadio.dial except using the
+ * @1.3::EmergencyServiceCategory as the input param.
+ *
+ * @param serial Serial number of request.
+ * @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial.
+ * @param categories bitfield<@1.3::EmergencyServiceCategory> the Emergency Service Category(s)
+ * of the call.
+ *
+ * Response function is IRadioResponse.emergencyDialResponse()
+ */
+ oneway emergencyDial(int32_t serial, Dial dialInfo,
+ bitfield<EmergencyServiceCategory> categories);
};
diff --git a/radio/1.3/IRadioIndication.hal b/radio/1.3/IRadioIndication.hal
new file mode 100644
index 0000000..c80e762
--- /dev/null
+++ b/radio/1.3/IRadioIndication.hal
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio@1.3;
+
+import @1.0::RadioIndicationType;
+import @1.2::IRadioIndication;
+
+/**
+ * Interface declaring unsolicited radio indications.
+ */
+interface IRadioIndication extends @1.2::IRadioIndication {
+ /**
+ * Indicate and update all of the current Emergency Number information known to the radio,
+ * when any of the Emergency Number sources (For example, network operator signals, sim card
+ * information, modem configuration, OEM configuration or system properties, etc.) change the
+ * list of emergency numbers.
+ *
+ * 112, 911 are always available. Besides, 000, 08, 110, 999, 118 and 119 should be available
+ * when sim is not present.
+ *
+ * This should be the same information as returned by getCurrentEmergencyNumberList() in
+ * 1.3::IRadio.
+ *
+ * The indicated list of emergency numbers should not have duplicate @1.3::EmergencyNumber.
+ * Please refer the document of @1.3::EmergencyNumber to construct each emergency number to be
+ * returned.
+ *
+ * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
+ *
+ * @param type Type of radio indication
+ * @param emergencyNumberList List of current Emergency Number information
+ * (@1.3::EmergencyNumber) known to radio. Radio must collect all sources of the emergency
+ * numbers to build the indication. For example, network operator signals, sim card
+ * information, modem configuration, OEM configuration (for example, OEM specific system
+ * properties), always-available emergency numbers and sim-absence emergency numbers, etc.
+ */
+ oneway currentEmergencyNumberList(RadioIndicationType type,
+ vec<EmergencyNumber> emergencyNumberList);
+};
diff --git a/radio/1.3/IRadioResponse.hal b/radio/1.3/IRadioResponse.hal
new file mode 100644
index 0000000..6912d0a
--- /dev/null
+++ b/radio/1.3/IRadioResponse.hal
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio@1.3;
+
+import @1.0::RadioResponseInfo;
+import @1.2::IRadioResponse;
+
+/**
+ * Interface declaring response functions to solicited radio requests.
+ */
+interface IRadioResponse extends @1.2::IRadioResponse {
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param emergencyNumberList List of current Emergency Number information known to radio.
+ *
+ * Radio must collect all sources of the emergency number to build the response. For example,
+ * network operator signals, sim card information, modem configuration, OEM configuration (for
+ * example, OEM system properties), always-available emergency numbers and sim-absence
+ * emergency numbers, etc.
+ *
+ * The returned list of emergency numbers must not have duplicate @1.3::EmergencyNumber. Please
+ * refer the document of @1.3::EmergencyNumber to construct each emergency number to be
+ * returned.
+ *
+ * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:NO_MEMORY
+ * RadioError:MODEM_ERR
+ */
+ oneway getCurrentEmergencyNumberListResponse(RadioResponseInfo info,
+ vec<EmergencyNumber> emergencyNumberList);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE (radio resetting)
+ * RadioError:DIAL_MODIFIED_TO_USSD
+ * RadioError:DIAL_MODIFIED_TO_SS
+ * RadioError:DIAL_MODIFIED_TO_DIAL
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_MEMORY
+ * RadioError:NO_RESOURCES
+ * RadioError:INTERNAL_ERR
+ * RadioError:FDN_CHECK_FAILURE
+ * RadioError:MODEM_ERR
+ * RadioError:NO_SUBSCRIPTION
+ * RadioError:NO_NETWORK_FOUND
+ * RadioError:INVALID_CALL_ID
+ * RadioError:DEVICE_IN_USE
+ * RadioError:ABORTED
+ * RadioError:INVALID_MODEM_STATE
+ * RadioError:CANCELLED
+ */
+ oneway emergencyDialResponse(RadioResponseInfo info);
+};
diff --git a/radio/1.3/types.hal b/radio/1.3/types.hal
index b80aabd..c04451f 100644
--- a/radio/1.3/types.hal
+++ b/radio/1.3/types.hal
@@ -24,3 +24,60 @@
*/
UNKNOWN = 0,
};
+
+/**
+ * Emergency number contains information of number, one or more service category(s), and mobile
+ * country code (mcc).
+ *
+ * If the source of the emergency number is associated with country, field ‘mcc’ must be
+ * provided; otherwise the field ‘mcc’ must be an empty string.
+ *
+ * A unique EmergencyNumber has a unique combination of ‘number’ and ‘mcc’ fields.
+ * Multiple @1.3::EmergencyServiceCategory should be merged into the bitfield for the same
+ * EmergencyNumber.
+ *
+ * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
+ */
+struct EmergencyNumber{
+ /**
+ * The emergency number. The character in the number string should only be the dial pad
+ * character('0'-'9', '*', or '#'). For example: 911.
+ */
+ string number;
+ /**
+ * 3-digit Mobile Country Code, 0..999. Empty string if not applicable.
+ */
+ string mcc;
+ /**
+ * The bitfield of @1.3::EmergencyServiceCategory(s). See @1.3::EmergencyServiceCategory for
+ * the value of each bit.
+ */
+ bitfield<EmergencyServiceCategory> categories;
+};
+
+/**
+ * Defining Emergency Service Category as follows:
+ * - General emergency call, all categories;
+ * - Police;
+ * - Ambulance;
+ * - Fire Brigade;
+ * - Marine Guard;
+ * - Mountain Rescue;
+ * - Manually Initiated eCall (MIeC);
+ * - Automatically Initiated eCall (AIeC);
+ *
+ * Type GENERIC (General emergency call, all categories) is considered to use if the reported type
+ * is not any of the other specific types.
+ *
+ * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
+ */
+enum EmergencyServiceCategory : int32_t {
+ GENERIC = 0, // General emergency call, all categories
+ POLICE = 1 << 0,
+ AMBULANCE = 1 << 1,
+ FIRE_BRIGADE = 1 << 2,
+ MARINE_GUARD = 1 << 3,
+ MOUNTAIN_RESCUE = 1 << 4,
+ MIEC = 1 << 5, // Manually Initiated eCall (MIeC)
+ AIEC = 1 << 6, // Automatically Initiated eCall (AIeC)
+};