Merge "Remove duplicated comment section" into rvc-dev
diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h
index a2f4116..8ef2b43 100644
--- a/audio/core/all-versions/vts/functional/ConfigHelper.h
+++ b/audio/core/all-versions/vts/functional/ConfigHelper.h
@@ -40,7 +40,7 @@
return devs.getDevice(AUDIO_DEVICE_IN_BUILTIN_MIC, {}, AUDIO_FORMAT_DEFAULT);
};
auto primaryMic = getMic(policyConfig.getPrimaryModule()->getDeclaredDevices());
- auto availableMic = getMic(policyConfig.getAvailableInputDevices());
+ auto availableMic = getMic(policyConfig.getInputDevices());
return primaryMic != nullptr && primaryMic->equals(availableMic);
}
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h
index e3cbf2e..f2d3c13 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h
@@ -206,7 +206,7 @@
InternalPool(VehiclePropertyType type, size_t vectorSize)
: mPropType(type), mVectorSize(vectorSize) {}
- RecyclableType obtain() {
+ RecyclableType obtain() override {
return ObjectPool<VehiclePropValue>::obtain();
}
protected:
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
index 6d5f23f..b76aff9 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -15,8 +15,9 @@
*/
#define LOG_TAG "DefaultVehicleHal_v2_0"
-#include <android/log.h>
#include <android-base/macros.h>
+#include <android/log.h>
+#include <sys/system_properties.h>
#include "EmulatedVehicleHal.h"
#include "JsonFakeValueGenerator.h"
@@ -186,6 +187,14 @@
return StatusCode::NOT_AVAILABLE;
}
+ if (mInEmulator && propValue.prop == toInt(VehicleProperty::DISPLAY_BRIGHTNESS)) {
+ // Emulator does not support remote brightness control, b/139959479
+ // do not send it down so that it does not bring unnecessary property change event
+ // return other error code, such NOT_AVAILABLE, causes Emulator to be freezing
+ // TODO: return StatusCode::NOT_AVAILABLE once the above issue is fixed
+ return StatusCode::OK;
+ }
+
/**
* After checking all conditions, such as the property is available, a real vhal will
* sent the events to Car ECU to take actions.
@@ -211,6 +220,17 @@
return false;
}
+// determine if it's running inside Android Emulator
+static bool isInEmulator() {
+ char propValue[PROP_VALUE_MAX];
+ bool isEmulator = (__system_property_get("ro.kernel.qemu", propValue) != 0);
+ if (!isEmulator) {
+ isEmulator = (__system_property_get("ro.hardware", propValue) != 0) &&
+ (!strcmp(propValue, "ranchu") || !strcmp(propValue, "goldfish"));
+ }
+ return isEmulator;
+}
+
// Parse supported properties list and generate vector of property values to hold current values.
void EmulatedVehicleHal::onCreate() {
static constexpr bool shouldUpdateStatus = true;
@@ -261,6 +281,8 @@
}
initObd2LiveFrame(*mPropStore->getConfigOrDie(OBD2_LIVE_FRAME));
initObd2FreezeFrame(*mPropStore->getConfigOrDie(OBD2_FREEZE_FRAME));
+ mInEmulator = isInEmulator();
+ ALOGD("mInEmulator=%s", mInEmulator ? "true" : "false");
}
std::vector<VehiclePropConfig> EmulatedVehicleHal::listProperties() {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
index ebf1995..dc05145 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -86,6 +86,7 @@
std::unordered_set<int32_t> mHvacPowerProps;
RecurrentTimer mRecurrentTimer;
VehicleHalClient* mVehicleClient;
+ bool mInEmulator;
};
} // impl
diff --git a/cas/1.2/vts/functional/Android.bp b/cas/1.2/vts/functional/Android.bp
index 9bc372c..2d6517f 100644
--- a/cas/1.2/vts/functional/Android.bp
+++ b/cas/1.2/vts/functional/Android.bp
@@ -31,6 +31,8 @@
shared_libs: [
"libbinder",
],
- test_suites: ["general-tests"],
+ test_suites: [
+ "general-tests",
+ "vts-core",
+ ],
}
-
diff --git a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp
index 8439ceb..58e0f2e 100644
--- a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp
+++ b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp
@@ -16,8 +16,6 @@
#define LOG_TAG "mediacas_hidl_hal_test"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
#include <android/hardware/cas/1.0/IDescramblerBase.h>
#include <android/hardware/cas/1.0/types.h>
@@ -28,8 +26,11 @@
#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <android/hardware/cas/native/1.0/types.h>
#include <binder/MemoryDealer.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
+#include <hidl/ServiceManagement.h>
#include <hidl/Status.h>
#include <hidlmemory/FrameworkUtils.h>
#include <utils/Condition.h>
@@ -293,27 +294,14 @@
EXPECT_EQ(mEventArg, static_cast<int32_t>(mode));
}
-// Test environment for Cas HIDL HAL.
-class CasHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static CasHidlEnvironment* Instance() {
- static CasHidlEnvironment* instance = new CasHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IMediaCasService>(); }
-};
-
-class MediaCasHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class MediaCasHidlTest : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- mService = ::testing::VtsHalHidlTargetTestBase::getService<IMediaCasService>(
- CasHidlEnvironment::Instance()->getServiceName<IMediaCasService>());
+ mService = IMediaCasService::getService(GetParam());
ASSERT_NE(mService, nullptr);
}
- sp<IMediaCasService> mService;
+ sp<IMediaCasService> mService = nullptr;
protected:
static void description(const std::string& description) {
@@ -497,7 +485,7 @@
return ::testing::AssertionResult(returnVoid.isOk());
}
-TEST_F(MediaCasHidlTest, TestClearKeyApisWithSession) {
+TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) {
description("Test that valid call sequences with SessionEvent send and receive");
ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
@@ -609,11 +597,7 @@
} // anonymous namespace
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(CasHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- CasHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, MediaCasHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMediaCasService::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/current.txt b/current.txt
index 873e2f6..d8f9c08 100644
--- a/current.txt
+++ b/current.txt
@@ -681,7 +681,7 @@
6e904be0ddca5ae1de8eba020e6c38ed935ea7d80cd08f47787f137a0ca58555 android.hardware.neuralnetworks@1.3::IFencedExecutionCallback
2b0b10d2ea7a18a4048cd0eb83d35c19a817aeee95f65807fc31f4ef21381397 android.hardware.neuralnetworks@1.3::IPreparedModel
eee3430cc86c97c7b407495863d8fb61da6f1a64b7721e77b9b4909b11b174e9 android.hardware.neuralnetworks@1.3::IPreparedModelCallback
-c9320b04ec302624985180a02d591bea5e435601fc411a6cabb58878e4e1ad68 android.hardware.neuralnetworks@1.3::types
+e442ab1b440327fe4e8a3b0b8ac6874e9bc6342e91fe976eb9fea77c63961ec8 android.hardware.neuralnetworks@1.3::types
b335c3c732c799b299fa61c6de6260ab4d20cbd0ec21acd6db14d8156c745d0b android.hardware.tv.tuner@1.0::types
adab52e647d1a1ccfbdabdfc9c73352f8e834b61322e505bc6e3d3a0d3acc259 android.hardware.tv.tuner@1.0::IDemux
548e1a16fc4f779346e14968a63cd6f160e1e2c8b8c99256b2bac24a24b52a9a android.hardware.tv.tuner@1.0::IDescrambler
diff --git a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
index 1185945..3d792f9 100644
--- a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
+++ b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
@@ -94,7 +94,7 @@
mDummyDescriptorInfo.width);
ASSERT_EQ(Error::BAD_BUFFER, ret)
<< "validateBufferSize with raw buffer handle did not fail with BAD_BUFFER";
- native_handle_delete(rawBufferHandle);
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(rawBufferHandle));
}
/**
@@ -179,11 +179,11 @@
ASSERT_NO_FATAL_FAILURE(rawBufferHandle = const_cast<native_handle_t*>(
mGralloc->allocate(mDummyDescriptorInfo, false)));
mGralloc->getMapper()->getTransportSize(
- invalidHandle, [&](const auto& tmpError, const auto&, const auto&) {
- ASSERT_EQ(Error::BAD_BUFFER, tmpError)
- << "getTransportSize with raw buffer handle did not fail with BAD_BUFFER";
- });
- native_handle_delete(rawBufferHandle);
+ rawBufferHandle, [&](const auto& tmpError, const auto&, const auto&) {
+ ASSERT_EQ(Error::BAD_BUFFER, tmpError)
+ << "getTransportSize with raw buffer handle did not fail with BAD_BUFFER";
+ });
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(rawBufferHandle));
}
/**
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 6cc5e34..a783eaa 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -2124,8 +2124,14 @@
Error err;
mGralloc->getAllocator()->allocate(
- descriptor, 1,
- [&](const auto& tmpError, const auto&, const auto&) { err = tmpError; });
+ descriptor, 1, [&](const auto& tmpError, const auto&, const auto& tmpBuffers) {
+ err = tmpError;
+ if (err == Error::NONE) {
+ ASSERT_EQ(1, tmpBuffers.size());
+ ASSERT_NO_FATAL_FAILURE(bufferHandle =
+ mGralloc->importBuffer(tmpBuffers[0]));
+ }
+ });
if (err == Error::UNSUPPORTED) {
continue;
}
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index 31a1a81..7c1faee 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -28,7 +28,7 @@
],
header_libs: [
"libbase_headers",
- ]
+ ],
}
cc_test {
@@ -39,9 +39,9 @@
"CompilationCachingTests.cpp",
"GeneratedTestHarness.cpp",
"TestAssertions.cpp",
+ "ValidateBurst.cpp",
"ValidateModel.cpp",
"ValidateRequest.cpp",
- "ValidateBurst.cpp",
"VtsHalNeuralnetworks.cpp",
],
local_include_dirs: ["include"],
@@ -50,18 +50,17 @@
"libnativewindow",
],
static_libs: [
+ "VtsHalNeuralNetworksV1_0_utils",
+ "VtsHalNeuralNetworksV1_2Callbacks",
"android.hardware.neuralnetworks@1.0",
"android.hardware.neuralnetworks@1.1",
"android.hardware.neuralnetworks@1.2",
- "android.hardware.neuralnetworks@1.3",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
"libgmock",
"libhidlmemory",
"libneuralnetworks_generated_test_harness",
"libneuralnetworks_utils",
- "VtsHalNeuralNetworksV1_0_utils",
- "VtsHalNeuralNetworksV1_2Callbacks",
],
whole_static_libs: [
"neuralnetworks_generated_V1_0_example",
@@ -71,5 +70,8 @@
header_libs: [
"libneuralnetworks_headers",
],
- test_suites: ["general-tests", "vts-core"],
+ test_suites: [
+ "general-tests",
+ "vts-core",
+ ],
}
diff --git a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
index 10dec79..449b8f3 100644
--- a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
@@ -32,7 +32,6 @@
#include "GeneratedTestHarness.h"
#include "MemoryUtils.h"
#include "TestHarness.h"
-#include "Utils.h"
#include "VtsHalNeuralnetworks.h"
// Forward declaration of the mobilenet generated test models in
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
index 4c8fede..3ab0135 100644
--- a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
@@ -43,7 +43,6 @@
#include "ExecutionBurstController.h"
#include "MemoryUtils.h"
#include "TestHarness.h"
-#include "Utils.h"
#include "VtsHalNeuralnetworks.h"
namespace android::hardware::neuralnetworks::V1_2::vts::functional {
@@ -273,7 +272,7 @@
int n;
std::tie(n, outputShapes, timing, std::ignore) =
controller->compute(request, testConfig.measureTiming, keys);
- executionStatus = nn::convertToV1_0(nn::convertResultCodeToErrorStatus(n));
+ executionStatus = nn::legacyConvertResultCodeToErrorStatus(n);
break;
}
diff --git a/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp b/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
index ec9629b..cc9d804 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
@@ -23,7 +23,6 @@
#include "ExecutionBurstServer.h"
#include "GeneratedTestHarness.h"
#include "TestHarness.h"
-#include "Utils.h"
#include <android-base/logging.h>
#include <chrono>
@@ -296,8 +295,7 @@
// collect serialized result by running regular burst
const auto [nRegular, outputShapesRegular, timingRegular, fallbackRegular] =
controllerRegular->compute(request, MeasureTiming::NO, keys);
- const ErrorStatus statusRegular =
- nn::convertToV1_0(nn::convertResultCodeToErrorStatus(nRegular));
+ const ErrorStatus statusRegular = nn::legacyConvertResultCodeToErrorStatus(nRegular);
EXPECT_FALSE(fallbackRegular);
// skip test if regular burst output isn't useful for testing a failure
@@ -313,7 +311,7 @@
// large enough to return the serialized result
const auto [nSmall, outputShapesSmall, timingSmall, fallbackSmall] =
controllerSmall->compute(request, MeasureTiming::NO, keys);
- const ErrorStatus statusSmall = nn::convertToV1_0(nn::convertResultCodeToErrorStatus(nSmall));
+ const ErrorStatus statusSmall = nn::legacyConvertResultCodeToErrorStatus(nSmall);
EXPECT_NE(ErrorStatus::NONE, statusSmall);
EXPECT_EQ(0u, outputShapesSmall.size());
EXPECT_TRUE(badTiming(timingSmall));
diff --git a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
index 7b5ff9b..8498cb0 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
@@ -22,7 +22,6 @@
#include "ExecutionBurstController.h"
#include "GeneratedTestHarness.h"
#include "TestHarness.h"
-#include "Utils.h"
#include "VtsHalNeuralnetworks.h"
namespace android::hardware::neuralnetworks::V1_2::vts::functional {
@@ -107,7 +106,7 @@
// execute and verify
const auto [n, outputShapes, timing, fallback] = burst->compute(request, measure, keys);
- const ErrorStatus status = nn::convertToV1_0(nn::convertResultCodeToErrorStatus(n));
+ const ErrorStatus status = nn::legacyConvertResultCodeToErrorStatus(n);
EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
EXPECT_EQ(outputShapes.size(), 0);
EXPECT_TRUE(badTiming(timing));
diff --git a/neuralnetworks/1.3/types.hal b/neuralnetworks/1.3/types.hal
index daaf22e..25ec915 100644
--- a/neuralnetworks/1.3/types.hal
+++ b/neuralnetworks/1.3/types.hal
@@ -5168,6 +5168,8 @@
* * {@link OperandType::TENSOR_FLOAT16}
* * {@link OperandType::TENSOR_FLOAT32}
*
+ * Supported tensor rank: from 1.
+ *
* Inputs:
* * 0: A tensor, specifying the input. May be zero-sized.
* * 1: A scalar, specifying the alpha parameter.
@@ -5197,6 +5199,8 @@
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
* * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
*
+ * Supported tensor rank: from 1.
+ *
* Inputs:
* * 0: A tensor, specifying the input. May be zero-sized.
*
@@ -5215,6 +5219,8 @@
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_INT32}
*
+ * Supported tensor rank: from 1.
+ *
* Inputs:
* * 0: A 1-D tensor, specifying the desired output tensor shape.
* * 1: A scalar, specifying the value to fill the output tensors with.
@@ -5248,6 +5254,8 @@
* * {@link OperandType::TENSOR_QUANT8_SYMM}
* * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
*
+ * Supported tensor rank: from 1.
+ *
* Inputs:
* * 0: The input tensor.
*
diff --git a/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp b/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp
index 6ff9dfd..aecb7b7 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp
@@ -23,7 +23,6 @@
#include "ExecutionBurstServer.h"
#include "GeneratedTestHarness.h"
#include "TestHarness.h"
-#include "Utils.h"
#include <android-base/logging.h>
#include <chrono>
@@ -302,8 +301,7 @@
// collect serialized result by running regular burst
const auto [nRegular, outputShapesRegular, timingRegular, fallbackRegular] =
controllerRegular->compute(request, MeasureTiming::NO, keys);
- const V1_0::ErrorStatus statusRegular =
- nn::convertToV1_0(nn::convertResultCodeToErrorStatus(nRegular));
+ const V1_0::ErrorStatus statusRegular = nn::legacyConvertResultCodeToErrorStatus(nRegular);
EXPECT_FALSE(fallbackRegular);
// skip test if regular burst output isn't useful for testing a failure
@@ -319,8 +317,7 @@
// large enough to return the serialized result
const auto [nSmall, outputShapesSmall, timingSmall, fallbackSmall] =
controllerSmall->compute(request, MeasureTiming::NO, keys);
- const V1_0::ErrorStatus statusSmall =
- nn::convertToV1_0(nn::convertResultCodeToErrorStatus(nSmall));
+ const V1_0::ErrorStatus statusSmall = nn::legacyConvertResultCodeToErrorStatus(nSmall);
EXPECT_NE(V1_0::ErrorStatus::NONE, statusSmall);
EXPECT_EQ(0u, outputShapesSmall.size());
EXPECT_TRUE(badTiming(timingSmall));
diff --git a/rebootescrow/aidl/default/HadamardUtils.cpp b/rebootescrow/aidl/default/HadamardUtils.cpp
index d2422b9..adb2010 100644
--- a/rebootescrow/aidl/default/HadamardUtils.cpp
+++ b/rebootescrow/aidl/default/HadamardUtils.cpp
@@ -16,8 +16,6 @@
#include <HadamardUtils.h>
-#include <limits>
-
#include <android-base/logging.h>
namespace aidl {
@@ -92,6 +90,31 @@
return result;
}
+// Constant-time conditional copy, to fix b/146520538
+// ctl must be 0 or 1; we do the copy if it's 1.
+static void CondCopy(uint32_t ctl, void* dest, const void* src, size_t len) {
+ const auto cdest = reinterpret_cast<uint8_t*>(dest);
+ const auto csrc = reinterpret_cast<const uint8_t*>(src);
+ for (size_t i = 0; i < len; i++) {
+ const uint32_t d = cdest[i];
+ const uint32_t s = csrc[i];
+ cdest[i] = d ^ (-ctl & (s ^ d));
+ }
+}
+
+struct CodewordWinner {
+ uint16_t codeword;
+ int32_t score;
+};
+
+// Replace dest with src if it has a higher score
+static void CopyWinner(CodewordWinner* dest, const CodewordWinner& src) {
+ // Scores are between - 2^15 and 2^15, so taking the difference won't
+ // overflow; we use the sign bit of the difference here.
+ CondCopy(static_cast<uint32_t>(dest->score - src.score) >> 31, dest, &src,
+ sizeof(CodewordWinner));
+}
+
// Decode a single codeword. Because of the way codewords are striped together
// this takes the entire input, plus an offset telling it which word to decode.
static uint16_t DecodeWord(size_t word, const std::vector<uint8_t>& encoded) {
@@ -118,20 +141,15 @@
}
}
}
- auto hiscore = std::numeric_limits<int32_t>::min();
- uint16_t winner;
- // TODO(b/146520538): this needs to be constant time
+ // -ENCODE_LENGTH is least possible score, so start one less than that
+ auto best = CodewordWinner{0, -static_cast<int32_t>(ENCODE_LENGTH + 1)};
+ // For every possible codeword value, look at its score, and replace best if it's higher,
+ // in constant time.
for (size_t i = 0; i < ENCODE_LENGTH; i++) {
- if (scores[i] > hiscore) {
- winner = i;
- hiscore = scores[i];
-
- } else if (-scores[i] > hiscore) {
- winner = i | (1 << CODE_K);
- hiscore = -scores[i];
- }
+ CopyWinner(&best, CodewordWinner{static_cast<uint16_t>(i), scores[i]});
+ CopyWinner(&best, CodewordWinner{static_cast<uint16_t>(i | (1 << CODE_K)), -scores[i]});
}
- return winner;
+ return best.codeword;
}
std::vector<uint8_t> DecodeKey(const std::vector<uint8_t>& shuffled) {
diff --git a/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl b/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
index 84556b5..406a899 100644
--- a/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
@@ -23,6 +23,9 @@
/* Period of silence preceding primitive. */
int delayMs;
CompositePrimitive primitive;
- /* 0.0 (exclusive) - 1.0 (inclusive) */
+ /*
+ * 0.0 (inclusive) - 1.0 (inclusive),
+ * where 0.0 is minimum "feelable" amplitude.
+ */
float scale;
}
diff --git a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
index 0fdfa5d..8e82db0 100644
--- a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
@@ -21,37 +21,53 @@
enum CompositePrimitive {
/**
* No haptic effect. Used to generate extended delays between primitives.
+ *
+ * Support is required.
*/
NOOP,
/**
* This effect should produce a sharp, crisp click sensation.
+ *
+ * Support is required.
*/
CLICK,
/**
* A haptic effect that simulates downwards movement with gravity. Often
* followed by extra energy of hitting and reverberation to augment
* physicality.
+ *
+ * Support is optional.
*/
THUD,
/**
* A haptic effect that simulates spinning momentum.
+ *
+ * Support is optional.
*/
SPIN,
/**
* A haptic effect that simulates quick upward movement against gravity.
+ *
+ * Support is required.
*/
QUICK_RISE,
/**
* A haptic effect that simulates slow upward movement against gravity.
+ *
+ * Support is required.
*/
SLOW_RISE,
/**
* A haptic effect that simulates quick downwards movement with gravity.
+ *
+ * Support is required.
*/
QUICK_FALL,
/**
* This very short effect should produce a light crisp sensation intended
* to be used repetitively for dynamic feedback.
+ *
+ * Support is required.
*/
LIGHT_TICK,
}
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
index 6489c1d..0b21248 100644
--- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
@@ -161,8 +161,8 @@
* List of supported effect primitive.
*
* Return the effect primitives which are supported by the compose API.
- * Implementations are expected to support all primitives of the interface
- * version that they implement.
+ * Implementations are expected to support all required primitives of the
+ * interface version that they implement (see primitive definitions).
*/
CompositePrimitive[] getSupportedPrimitives();
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index 9236b95..b359100 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -146,7 +146,7 @@
if (e.delayMs > kComposeDelayMaxMs) {
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- if (e.scale <= 0.0f || e.scale > 1.0f) {
+ if (e.scale < 0.0f || e.scale > 1.0f) {
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
if (std::find(supported.begin(), supported.end(), e.primitive) == supported.end()) {
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 411fe7a..8340517 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -21,6 +21,7 @@
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
+#include <cmath>
#include <future>
using android::ProcessState;
@@ -53,6 +54,11 @@
android::enum_range<CompositePrimitive>().begin(),
android::enum_range<CompositePrimitive>().end()};
+const std::vector<CompositePrimitive> kOptionalPrimitives = {
+ CompositePrimitive::THUD,
+ CompositePrimitive::SPIN,
+};
+
const std::vector<CompositePrimitive> kInvalidPrimitives = {
static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.front()) - 1),
static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.back()) + 1),
@@ -128,7 +134,6 @@
} else {
EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
<< toString(effect) << " " << toString(strength);
- EXPECT_EQ(lengthMs, 0);
}
}
}
@@ -157,7 +162,6 @@
EXPECT_GT(lengthMs, 0);
} else {
EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
- EXPECT_EQ(lengthMs, 0);
}
if (!status.isOk()) continue;
@@ -177,7 +181,6 @@
int lengthMs;
Status status = vibrator->perform(effect, strength, callback, &lengthMs);
EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
- EXPECT_EQ(lengthMs, 0);
}
}
}
@@ -267,38 +270,56 @@
EXPECT_EQ(Status::EX_NONE, vibrator->getSupportedPrimitives(&supported).exceptionCode());
- std::sort(supported.begin(), supported.end());
+ for (auto primitive : kCompositePrimitives) {
+ bool isPrimitiveSupported =
+ std::find(supported.begin(), supported.end(), primitive) != supported.end();
+ bool isPrimitiveOptional =
+ std::find(kOptionalPrimitives.begin(), kOptionalPrimitives.end(), primitive) !=
+ kOptionalPrimitives.end();
- EXPECT_EQ(kCompositePrimitives, supported);
+ EXPECT_TRUE(isPrimitiveSupported || isPrimitiveOptional) << toString(primitive);
+ }
}
}
TEST_P(VibratorAidl, GetPrimitiveDuration) {
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
- int32_t duration;
+ std::vector<CompositePrimitive> supported;
+ ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
for (auto primitive : kCompositePrimitives) {
- EXPECT_EQ(Status::EX_NONE,
- vibrator->getPrimitiveDuration(primitive, &duration).exceptionCode());
+ bool isPrimitiveSupported =
+ std::find(supported.begin(), supported.end(), primitive) != supported.end();
+ int32_t duration;
+
+ Status status = vibrator->getPrimitiveDuration(primitive, &duration);
+
+ if (isPrimitiveSupported) {
+ EXPECT_EQ(Status::EX_NONE, status.exceptionCode());
+ } else {
+ EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
+ }
}
}
}
TEST_P(VibratorAidl, ComposeValidPrimitives) {
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+ std::vector<CompositePrimitive> supported;
int32_t maxDelay, maxSize;
+ ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
std::vector<CompositeEffect> composite;
- for (auto primitive : kCompositePrimitives) {
+ for (auto primitive : supported) {
CompositeEffect effect;
effect.delayMs = std::rand() % (maxDelay + 1);
effect.primitive = primitive;
- effect.scale = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
+ effect.scale = static_cast<float>(std::rand()) / RAND_MAX;
composite.emplace_back(effect);
if (composite.size() == maxSize) {
@@ -317,7 +338,21 @@
TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
- for (auto primitive : kInvalidPrimitives) {
+ auto unsupported = kInvalidPrimitives;
+ std::vector<CompositePrimitive> supported;
+
+ ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
+
+ for (auto primitive : kCompositePrimitives) {
+ bool isPrimitiveSupported =
+ std::find(supported.begin(), supported.end(), primitive) != supported.end();
+
+ if (!isPrimitiveSupported) {
+ unsupported.push_back(primitive);
+ }
+ }
+
+ for (auto primitive : unsupported) {
std::vector<CompositeEffect> composite(1);
for (auto& effect : composite) {
@@ -332,7 +367,33 @@
}
}
-TEST_P(VibratorAidl, CompseDelayBoundary) {
+TEST_P(VibratorAidl, ComposeScaleBoundary) {
+ if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+ std::vector<CompositeEffect> composite(1);
+ CompositeEffect& effect = composite[0];
+
+ effect.delayMs = 0;
+ effect.primitive = CompositePrimitive::CLICK;
+
+ effect.scale = std::nextafter(0.0f, -1.0f);
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+ vibrator->compose(composite, nullptr).exceptionCode());
+
+ effect.scale = 0.0f;
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+
+ effect.scale = 1.0f;
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+
+ effect.scale = std::nextafter(1.0f, 2.0f);
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+ vibrator->compose(composite, nullptr).exceptionCode());
+
+ vibrator->off();
+ }
+}
+
+TEST_P(VibratorAidl, ComposeDelayBoundary) {
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
int32_t maxDelay;
@@ -357,7 +418,7 @@
}
}
-TEST_P(VibratorAidl, CompseSizeBoundary) {
+TEST_P(VibratorAidl, ComposeSizeBoundary) {
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
int32_t maxSize;