Merge "WifiHal: Correct typo for code comment" am: 12ca95ccc4 am: 2ad166a35b
am: 29a52adadc
Change-Id: I579de2e0277ecf4a9bf720698359ca647345d53d
diff --git a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
index 6106a67..ee236ba 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
@@ -66,6 +66,11 @@
* each received location.
*/
TEST_F(GnssHalTest, GetLocationLowPower) {
+ if (!IsGnssHalVersion_1_1()) {
+ ALOGI("Test GetLocationLowPower skipped. GNSS HAL version is greater than 1.1.");
+ return;
+ }
+
const int kMinIntervalMsec = 5000;
const int kLocationTimeoutSubsequentSec = (kMinIntervalMsec / 1000) * 2;
const int kNoLocationPeriodSec = (kMinIntervalMsec / 1000) / 2;
diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
index 6e0887f..39736cc 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -416,6 +416,70 @@
}
/*
+ * GetLocationLowPower:
+ * Turns on location, waits for at least 5 locations allowing max of LOCATION_TIMEOUT_SUBSEQUENT_SEC
+ * between one location and the next. Also ensure that MIN_INTERVAL_MSEC is respected by waiting
+ * NO_LOCATION_PERIOD_SEC and verfiy that no location is received. Also perform validity checks on
+ * each received location.
+ */
+TEST_F(GnssHalTest, GetLocationLowPower) {
+ if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::LOW_POWER_MODE)) {
+ ALOGI("Test GetLocationLowPower skipped. LOW_POWER_MODE capability not supported.");
+ return;
+ }
+
+ const int kMinIntervalMsec = 5000;
+ const int kLocationTimeoutSubsequentSec = (kMinIntervalMsec / 1000) * 2;
+ const int kNoLocationPeriodSec = (kMinIntervalMsec / 1000) / 2;
+ const int kLocationsToCheck = 5;
+ const bool kLowPowerMode = true;
+
+ // Warmup period - VTS doesn't have AGPS access via GnssLocationProvider
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToCheck);
+ StopAndClearLocations();
+ gnss_cb_->location_cbq_.reset();
+
+ // Start of Low Power Mode test
+ SetPositionMode(kMinIntervalMsec, kLowPowerMode);
+
+ // Don't expect true - as without AGPS access
+ if (!StartAndCheckFirstLocation()) {
+ ALOGW("GetLocationLowPower test - no first low power location received.");
+ }
+
+ for (int i = 1; i < kLocationsToCheck; i++) {
+ // Verify that kMinIntervalMsec is respected by waiting kNoLocationPeriodSec and
+ // ensure that no location is received yet
+
+ gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, kNoLocationPeriodSec);
+ const int locationCalledCount = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate (ignore) one extra location right after the first one
+ // to handle startup edge case scheduling limitations in some implementations
+ if ((i == 1) && (locationCalledCount == 2)) {
+ CheckLocation(gnss_cb_->last_location_, true);
+ continue; // restart the quiet wait period after this too-fast location
+ }
+ EXPECT_LE(locationCalledCount, i);
+ if (locationCalledCount != i) {
+ ALOGW("GetLocationLowPower test - not enough locations received. %d vs. %d expected ",
+ locationCalledCount, i);
+ }
+
+ if (!gnss_cb_->location_cbq_.retrieve(
+ gnss_cb_->last_location_,
+ kLocationTimeoutSubsequentSec - kNoLocationPeriodSec)) {
+ ALOGW("GetLocationLowPower test - timeout awaiting location %d", i);
+ } else {
+ CheckLocation(gnss_cb_->last_location_, true);
+ }
+ }
+
+ StopAndClearLocations();
+}
+
+/*
* MapConstellationType:
* Given a GnssConstellationType_2_0 type constellation, maps to its equivalent
* GnssConstellationType_1_0 type constellation. For constellations that do not have
@@ -537,6 +601,8 @@
*/
TEST_F(GnssHalTest, BlacklistIndividualSatellites) {
if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) {
+ ALOGI("Test BlacklistIndividualSatellites skipped. SATELLITE_BLACKLIST capability"
+ " not supported.");
return;
}
@@ -680,6 +746,7 @@
*/
TEST_F(GnssHalTest, BlacklistConstellation) {
if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) {
+ ALOGI("Test BlacklistConstellation skipped. SATELLITE_BLACKLIST capability not supported.");
return;
}
diff --git a/sensors/1.0/vts/functional/Android.bp b/sensors/1.0/vts/functional/Android.bp
index d4c5f32..7bb992b 100644
--- a/sensors/1.0/vts/functional/Android.bp
+++ b/sensors/1.0/vts/functional/Android.bp
@@ -16,6 +16,7 @@
cc_test {
name: "VtsHalSensorsV1_0TargetTest",
+ cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""],
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
"SensorsHidlEnvironmentV1_0.cpp",
@@ -23,7 +24,10 @@
],
static_libs: [
"android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@2.1",
+ "android.hardware.graphics.mapper@3.0",
"android.hardware.sensors@1.0",
"VtsHalSensorsTargetTestUtils",
],
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index 47308e1..5453ef6 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#define LOG_TAG "sensors_hidl_hal_test"
-
#include "SensorsHidlEnvironmentV1_0.h"
#include "sensors-vts-utils/SensorsHidlTestBase.h"
diff --git a/sensors/2.0/vts/functional/Android.bp b/sensors/2.0/vts/functional/Android.bp
index 8e8413c..4765fa2 100644
--- a/sensors/2.0/vts/functional/Android.bp
+++ b/sensors/2.0/vts/functional/Android.bp
@@ -16,6 +16,7 @@
cc_test {
name: "VtsHalSensorsV2_0TargetTest",
+ cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""],
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
"SensorsHidlEnvironmentV2_0.cpp",
@@ -23,7 +24,10 @@
],
static_libs: [
"android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@2.1",
+ "android.hardware.graphics.mapper@3.0",
"android.hardware.sensors@1.0",
"android.hardware.sensors@2.0",
"libfmq",
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
index 0525bdc..03fcc17 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
@@ -38,6 +38,13 @@
constexpr size_t SensorsHidlEnvironmentV2_0::MAX_RECEIVE_BUFFER_EVENT_COUNT;
+void SensorsHalDeathRecipient::serviceDied(
+ uint64_t /* cookie */,
+ const ::android::wp<::android::hidl::base::V1_0::IBase>& /* service */) {
+ ALOGE("Sensors HAL died (likely crashed) during test");
+ FAIL() << "Sensors HAL died during test";
+}
+
struct SensorsCallback : ISensorsCallback {
Return<void> onDynamicSensorsConnected(const hidl_vec<SensorInfo>& /* sensorInfos */) {
return Return<void>();
@@ -56,6 +63,7 @@
if (mSensors == nullptr) {
break;
}
+ mSensors->linkToDeath(mDeathRecipient, 0 /* cookie */);
// Initialize FMQs
mEventQueue = std::make_unique<EventMessageQueue>(MAX_RECEIVE_BUFFER_EVENT_COUNT,
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
index 5e54530..b0dbd90 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
@@ -32,6 +32,13 @@
using ::android::hardware::MessageQueue;
class SensorsHidlTest;
+
+class SensorsHalDeathRecipient : public ::android::hardware::hidl_death_recipient {
+ virtual void serviceDied(
+ uint64_t cookie,
+ const ::android::wp<::android::hidl::base::V1_0::IBase>& service) override;
+};
+
class SensorsHidlEnvironmentV2_0 : public SensorsHidlEnvironmentBase {
public:
using Event = ::android::hardware::sensors::V1_0::Event;
@@ -84,6 +91,11 @@
sp<android::hardware::sensors::V2_0::ISensors> mSensors;
/**
+ * Monitors the HAL for crashes, triggering test failure if seen
+ */
+ sp<SensorsHalDeathRecipient> mDeathRecipient = new SensorsHalDeathRecipient();
+
+ /**
* Type used to simplify the creation of the Event FMQ
*/
typedef MessageQueue<Event, ::android::hardware::kSynchronizedReadWrite> EventMessageQueue;
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index 62c5334..8364ba9 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#define LOG_TAG "sensors_hidl_hal_test"
-
#include "SensorsHidlEnvironmentV2_0.h"
#include "sensors-vts-utils/SensorsHidlTestBase.h"
#include "sensors-vts-utils/SensorsTestSharedMemory.h"
@@ -40,6 +38,10 @@
using ::android::hardware::sensors::V1_0::SensorStatus;
using ::android::hardware::sensors::V1_0::SharedMemType;
using ::android::hardware::sensors::V1_0::Vec3;
+using std::chrono::duration_cast;
+using std::chrono::microseconds;
+using std::chrono::milliseconds;
+using std::chrono::nanoseconds;
constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH);
@@ -69,9 +71,9 @@
}
void waitForFlushEvents(const std::vector<SensorInfo>& sensorsToWaitFor,
- int32_t numCallsToFlush, int64_t timeoutMs) {
+ int32_t numCallsToFlush, milliseconds timeout) {
std::unique_lock<std::recursive_mutex> lock(mFlushMutex);
- mFlushCV.wait_for(lock, std::chrono::milliseconds(timeoutMs),
+ mFlushCV.wait_for(lock, timeout,
[&] { return flushesReceived(sensorsToWaitFor, numCallsToFlush); });
}
@@ -80,10 +82,9 @@
return mEventMap[sensorHandle];
}
- void waitForEvents(const std::vector<SensorInfo>& sensorsToWaitFor, int32_t timeoutMs) {
+ void waitForEvents(const std::vector<SensorInfo>& sensorsToWaitFor, milliseconds timeout) {
std::unique_lock<std::recursive_mutex> lock(mEventMutex);
- mEventCV.wait_for(lock, std::chrono::milliseconds(timeoutMs),
- [&] { return eventsReceived(sensorsToWaitFor); });
+ mEventCV.wait_for(lock, timeout, [&] { return eventsReceived(sensorsToWaitFor); });
}
protected:
@@ -117,7 +118,13 @@
// The main test class for SENSORS HIDL HAL.
class SensorsHidlTest : public SensorsHidlTestBase {
- protected:
+ public:
+ virtual void SetUp() override {
+ // Ensure that we have a valid environment before performing tests
+ ASSERT_NE(getSensors(), nullptr);
+ }
+
+ protected:
SensorInfo defaultSensorByType(SensorType type) override;
std::vector<SensorInfo> getSensorsList();
// implementation wrapper
@@ -169,19 +176,21 @@
// Helper functions
void activateAllSensors(bool enable);
std::vector<SensorInfo> getNonOneShotSensors();
+ std::vector<SensorInfo> getNonOneShotAndNonSpecialSensors();
std::vector<SensorInfo> getOneShotSensors();
std::vector<SensorInfo> getInjectEventSensors();
int32_t getInvalidSensorHandle();
bool getDirectChannelSensor(SensorInfo* sensor, SharedMemType* memType, RateLevel* rate);
void verifyDirectChannel(SharedMemType memType);
- void verifyRegisterDirectChannel(const SensorInfo& sensor, SharedMemType memType,
- std::shared_ptr<SensorsTestSharedMemory> mem,
- int32_t* directChannelHandle);
+ void verifyRegisterDirectChannel(std::shared_ptr<SensorsTestSharedMemory> mem,
+ int32_t* directChannelHandle, bool supportsSharedMemType,
+ bool supportsAnyDirectChannel);
void verifyConfigure(const SensorInfo& sensor, SharedMemType memType,
- int32_t directChannelHandle);
- void verifyUnregisterDirectChannel(const SensorInfo& sensor, SharedMemType memType,
- int32_t directChannelHandle);
+ int32_t directChannelHandle, bool directChannelSupported);
+ void verifyUnregisterDirectChannel(int32_t directChannelHandle, bool directChannelSupported);
void checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle, RateLevel rateLevel);
+ void queryDirectChannelSupport(SharedMemType memType, bool* supportsSharedMemType,
+ bool* supportsAnyDirectChannel);
};
Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
@@ -250,6 +259,18 @@
return sensors;
}
+std::vector<SensorInfo> SensorsHidlTest::getNonOneShotAndNonSpecialSensors() {
+ std::vector<SensorInfo> sensors;
+ for (const SensorInfo& info : getSensorsList()) {
+ SensorFlagBits reportMode = extractReportMode(info.flags);
+ if (reportMode != SensorFlagBits::ONE_SHOT_MODE &&
+ reportMode != SensorFlagBits::SPECIAL_REPORTING_MODE) {
+ sensors.push_back(info);
+ }
+ }
+ return sensors;
+}
+
std::vector<SensorInfo> SensorsHidlTest::getOneShotSensors() {
std::vector<SensorInfo> sensors;
for (const SensorInfo& info : getSensorsList()) {
@@ -368,7 +389,7 @@
}
// Wait for events to be written back to the Event FMQ
- callback.waitForEvents(sensors, 1000 /* timeoutMs */);
+ callback.waitForEvents(sensors, milliseconds(1000) /* timeout */);
for (const auto& s : sensors) {
auto events = callback.getEvents(s.sensorHandle);
@@ -614,6 +635,9 @@
std::unique_ptr<SensorsHidlEnvironmentTest> newEnv =
std::make_unique<SensorsHidlEnvironmentTest>();
newEnv->HidlSetUp();
+ if (HasFatalFailure()) {
+ return; // Exit early if setting up the new environment failed
+ }
activateAllSensors(true);
// Verify that the old environment does not receive any events
@@ -626,8 +650,11 @@
newEnv->HidlTearDown();
// Restore the test environment for future tests
- SensorsHidlEnvironmentV2_0::Instance()->HidlTearDown();
- SensorsHidlEnvironmentV2_0::Instance()->HidlSetUp();
+ getEnvironment()->HidlTearDown();
+ getEnvironment()->HidlSetUp();
+ if (HasFatalFailure()) {
+ return; // Exit early if resetting the environment failed
+ }
// Ensure that the original environment is receiving events
activateAllSensors(true);
@@ -646,8 +673,11 @@
// Clear the active sensor handles so they are not disabled during TearDown
auto handles = mSensorHandles;
mSensorHandles.clear();
- getEnvironment()->TearDown();
- getEnvironment()->SetUp();
+ getEnvironment()->HidlTearDown();
+ getEnvironment()->HidlSetUp();
+ if (HasFatalFailure()) {
+ return; // Exit early if resetting the environment failed
+ }
// Verify no events are received until sensors are re-activated
ASSERT_EQ(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), 0);
@@ -686,7 +716,7 @@
}
// Wait up to one second for the flush events
- callback.waitForFlushEvents(sensors, flushCalls, 1000 /* timeoutMs */);
+ callback.waitForFlushEvents(sensors, flushCalls, milliseconds(1000) /* timeout */);
// Deactivate all sensors after waiting for flush events so pending flush events are not
// abandoned by the HAL.
@@ -761,7 +791,12 @@
activateAllSensors(false /* enable */);
for (const SensorInfo& sensor : getSensorsList()) {
// Call batch on inactive sensor
- ASSERT_EQ(batch(sensor.sensorHandle, sensor.minDelay, 0 /* maxReportLatencyNs */),
+ // One shot sensors have minDelay set to -1 which is an invalid
+ // parameter. Use 0 instead to avoid errors.
+ int64_t samplingPeriodNs = extractReportMode(sensor.flags) == SensorFlagBits::ONE_SHOT_MODE
+ ? 0
+ : sensor.minDelay;
+ ASSERT_EQ(batch(sensor.sensorHandle, samplingPeriodNs, 0 /* maxReportLatencyNs */),
Result::OK);
// Activate the sensor
@@ -807,17 +842,19 @@
}
TEST_F(SensorsHidlTest, NoStaleEvents) {
- constexpr int64_t kFiveHundredMilliseconds = 500 * 1000;
- constexpr int64_t kOneSecond = 1000 * 1000;
+ constexpr milliseconds kFiveHundredMs(500);
+ constexpr milliseconds kOneSecond(1000);
// Register the callback to receive sensor events
EventCallback callback;
getEnvironment()->registerCallback(&callback);
- const std::vector<SensorInfo> sensors = getSensorsList();
- int32_t maxMinDelay = 0;
- for (const SensorInfo& sensor : getSensorsList()) {
- maxMinDelay = std::max(maxMinDelay, sensor.minDelay);
+ // This test is not valid for one-shot or special-report-mode sensors
+ const std::vector<SensorInfo> sensors = getNonOneShotAndNonSpecialSensors();
+ milliseconds maxMinDelay(0);
+ for (const SensorInfo& sensor : sensors) {
+ milliseconds minDelay = duration_cast<milliseconds>(microseconds(sensor.minDelay));
+ maxMinDelay = milliseconds(std::max(maxMinDelay.count(), minDelay.count()));
}
// Activate the sensors so that they start generating events
@@ -826,33 +863,46 @@
// According to the CDD, the first sample must be generated within 400ms + 2 * sample_time
// and the maximum reporting latency is 100ms + 2 * sample_time. Wait a sufficient amount
// of time to guarantee that a sample has arrived.
- callback.waitForEvents(sensors, kFiveHundredMilliseconds + (5 * maxMinDelay));
+ callback.waitForEvents(sensors, kFiveHundredMs + (5 * maxMinDelay));
activateAllSensors(false);
// Save the last received event for each sensor
std::map<int32_t, int64_t> lastEventTimestampMap;
for (const SensorInfo& sensor : sensors) {
- ASSERT_GE(callback.getEvents(sensor.sensorHandle).size(), 1);
- lastEventTimestampMap[sensor.sensorHandle] =
- callback.getEvents(sensor.sensorHandle).back().timestamp;
+ // Some on-change sensors may not report an event without stimulus
+ if (extractReportMode(sensor.flags) != SensorFlagBits::ON_CHANGE_MODE) {
+ ASSERT_GE(callback.getEvents(sensor.sensorHandle).size(), 1);
+ }
+ if (callback.getEvents(sensor.sensorHandle).size() >= 1) {
+ lastEventTimestampMap[sensor.sensorHandle] =
+ callback.getEvents(sensor.sensorHandle).back().timestamp;
+ }
}
// Allow some time to pass, reset the callback, then reactivate the sensors
- usleep(kOneSecond + (5 * maxMinDelay));
+ usleep(duration_cast<microseconds>(kOneSecond + (5 * maxMinDelay)).count());
callback.reset();
activateAllSensors(true);
- callback.waitForEvents(sensors, kFiveHundredMilliseconds + (5 * maxMinDelay));
+ callback.waitForEvents(sensors, kFiveHundredMs + (5 * maxMinDelay));
activateAllSensors(false);
for (const SensorInfo& sensor : sensors) {
+ // Skip sensors that did not previously report an event
+ if (lastEventTimestampMap.find(sensor.sensorHandle) == lastEventTimestampMap.end()) {
+ continue;
+ }
+ // Skip on-change sensors that do not consistently report an initial event
+ if (callback.getEvents(sensor.sensorHandle).size() < 1) {
+ continue;
+ }
// Ensure that the first event received is not stale by ensuring that its timestamp is
// sufficiently different from the previous event
const Event newEvent = callback.getEvents(sensor.sensorHandle).front();
- int64_t delta = newEvent.timestamp - lastEventTimestampMap[sensor.sensorHandle];
- ASSERT_GE(delta, kFiveHundredMilliseconds + (3 * sensor.minDelay));
+ milliseconds delta = duration_cast<milliseconds>(
+ nanoseconds(newEvent.timestamp - lastEventTimestampMap[sensor.sensorHandle]));
+ milliseconds sensorMinDelay = duration_cast<milliseconds>(microseconds(sensor.minDelay));
+ ASSERT_GE(delta, kFiveHundredMs + (3 * sensorMinDelay));
}
-
- getEnvironment()->unregisterCallback();
}
void SensorsHidlTest::checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle,
@@ -861,21 +911,43 @@
[&](Result result, int32_t reportToken) {
if (isDirectReportRateSupported(sensor, rateLevel)) {
ASSERT_EQ(result, Result::OK);
- ASSERT_GT(reportToken, 0);
+ if (rateLevel != RateLevel::STOP) {
+ ASSERT_GT(reportToken, 0);
+ }
} else {
ASSERT_EQ(result, Result::BAD_VALUE);
}
});
}
-void SensorsHidlTest::verifyRegisterDirectChannel(const SensorInfo& sensor, SharedMemType memType,
- std::shared_ptr<SensorsTestSharedMemory> mem,
- int32_t* directChannelHandle) {
+void SensorsHidlTest::queryDirectChannelSupport(SharedMemType memType, bool* supportsSharedMemType,
+ bool* supportsAnyDirectChannel) {
+ *supportsSharedMemType = false;
+ *supportsAnyDirectChannel = false;
+ for (const SensorInfo& curSensor : getSensorsList()) {
+ if (isDirectChannelTypeSupported(curSensor, memType)) {
+ *supportsSharedMemType = true;
+ }
+ if (isDirectChannelTypeSupported(curSensor, SharedMemType::ASHMEM) ||
+ isDirectChannelTypeSupported(curSensor, SharedMemType::GRALLOC)) {
+ *supportsAnyDirectChannel = true;
+ }
+
+ if (*supportsSharedMemType && *supportsAnyDirectChannel) {
+ break;
+ }
+ }
+}
+
+void SensorsHidlTest::verifyRegisterDirectChannel(std::shared_ptr<SensorsTestSharedMemory> mem,
+ int32_t* directChannelHandle,
+ bool supportsSharedMemType,
+ bool supportsAnyDirectChannel) {
char* buffer = mem->getBuffer();
memset(buffer, 0xff, mem->getSize());
registerDirectChannel(mem->getSharedMemInfo(), [&](Result result, int32_t channelHandle) {
- if (isDirectChannelTypeSupported(sensor, memType)) {
+ if (supportsSharedMemType) {
ASSERT_EQ(result, Result::OK);
ASSERT_GT(channelHandle, 0);
@@ -884,7 +956,9 @@
ASSERT_EQ(buffer[i], 0x00);
}
} else {
- ASSERT_EQ(result, Result::INVALID_OPERATION);
+ Result expectedResult =
+ supportsAnyDirectChannel ? Result::BAD_VALUE : Result::INVALID_OPERATION;
+ ASSERT_EQ(result, expectedResult);
ASSERT_EQ(channelHandle, -1);
}
*directChannelHandle = channelHandle;
@@ -892,7 +966,7 @@
}
void SensorsHidlTest::verifyConfigure(const SensorInfo& sensor, SharedMemType memType,
- int32_t directChannelHandle) {
+ int32_t directChannelHandle, bool supportsAnyDirectChannel) {
if (isDirectChannelTypeSupported(sensor, memType)) {
// Verify that each rate level is properly supported
checkRateLevel(sensor, directChannelHandle, RateLevel::NORMAL);
@@ -908,22 +982,22 @@
-1 /* sensorHandle */, directChannelHandle, RateLevel::STOP,
[](Result result, int32_t /* reportToken */) { ASSERT_EQ(result, Result::OK); });
} else {
- // Direct channel is not supported for this SharedMemType
+ // directChannelHandle will be -1 here, HAL should either reject it as a bad value if there
+ // is some level of direct channel report, otherwise return INVALID_OPERATION if direct
+ // channel is not supported at all
+ Result expectedResult =
+ supportsAnyDirectChannel ? Result::BAD_VALUE : Result::INVALID_OPERATION;
configDirectReport(sensor.sensorHandle, directChannelHandle, RateLevel::NORMAL,
- [](Result result, int32_t /* reportToken */) {
- ASSERT_EQ(result, Result::INVALID_OPERATION);
+ [expectedResult](Result result, int32_t /* reportToken */) {
+ ASSERT_EQ(result, expectedResult);
});
}
}
-void SensorsHidlTest::verifyUnregisterDirectChannel(const SensorInfo& sensor, SharedMemType memType,
- int32_t directChannelHandle) {
- Result result = unregisterDirectChannel(directChannelHandle);
- if (isDirectChannelTypeSupported(sensor, memType)) {
- ASSERT_EQ(result, Result::OK);
- } else {
- ASSERT_EQ(result, Result::INVALID_OPERATION);
- }
+void SensorsHidlTest::verifyUnregisterDirectChannel(int32_t directChannelHandle,
+ bool supportsAnyDirectChannel) {
+ Result expectedResult = supportsAnyDirectChannel ? Result::OK : Result::INVALID_OPERATION;
+ ASSERT_EQ(unregisterDirectChannel(directChannelHandle), expectedResult);
}
void SensorsHidlTest::verifyDirectChannel(SharedMemType memType) {
@@ -934,11 +1008,16 @@
SensorsTestSharedMemory::create(memType, kMemSize));
ASSERT_NE(mem, nullptr);
+ bool supportsSharedMemType;
+ bool supportsAnyDirectChannel;
+ queryDirectChannelSupport(memType, &supportsSharedMemType, &supportsAnyDirectChannel);
+
for (const SensorInfo& sensor : getSensorsList()) {
int32_t directChannelHandle = 0;
- verifyRegisterDirectChannel(sensor, memType, mem, &directChannelHandle);
- verifyConfigure(sensor, memType, directChannelHandle);
- verifyUnregisterDirectChannel(sensor, memType, directChannelHandle);
+ verifyRegisterDirectChannel(mem, &directChannelHandle, supportsSharedMemType,
+ supportsAnyDirectChannel);
+ verifyConfigure(sensor, memType, directChannelHandle, supportsAnyDirectChannel);
+ verifyUnregisterDirectChannel(directChannelHandle, supportsAnyDirectChannel);
}
}
@@ -1030,8 +1109,11 @@
// Clear the active direct connections so they are not stopped during TearDown
auto handles = mDirectChannelHandles;
mDirectChannelHandles.clear();
- getEnvironment()->TearDown();
- getEnvironment()->SetUp();
+ getEnvironment()->HidlTearDown();
+ getEnvironment()->HidlSetUp();
+ if (HasFatalFailure()) {
+ return; // Exit early if resetting the environment failed
+ }
// Attempt to configure the direct channel and expect it to fail
configDirectReport(
diff --git a/sensors/common/vts/utils/Android.bp b/sensors/common/vts/utils/Android.bp
index 95df425..02dc608 100644
--- a/sensors/common/vts/utils/Android.bp
+++ b/sensors/common/vts/utils/Android.bp
@@ -16,6 +16,7 @@
cc_library_static {
name: "VtsHalSensorsTargetTestUtils",
+ cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""],
srcs: [
"GrallocWrapper.cpp",
"SensorsHidlEnvironmentBase.cpp",
@@ -30,7 +31,10 @@
],
static_libs: [
"android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@2.1",
+ "android.hardware.graphics.mapper@3.0",
"android.hardware.sensors@1.0",
"VtsHalHidlTargetTestBase",
],
diff --git a/sensors/common/vts/utils/GrallocWrapper.cpp b/sensors/common/vts/utils/GrallocWrapper.cpp
index 7bed16d..1cad913 100644
--- a/sensors/common/vts/utils/GrallocWrapper.cpp
+++ b/sensors/common/vts/utils/GrallocWrapper.cpp
@@ -14,211 +14,264 @@
* limitations under the License.
*/
-#define LOG_TAG "GrallocWrapper"
-
#include "GrallocWrapper.h"
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/mapper/2.1/IMapper.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+
#include <utils/Log.h>
+#include <cinttypes>
+#include <type_traits>
+
+using IAllocator2 = ::android::hardware::graphics::allocator::V2_0::IAllocator;
+using IAllocator3 = ::android::hardware::graphics::allocator::V3_0::IAllocator;
+using IMapper2 = ::android::hardware::graphics::mapper::V2_0::IMapper;
+using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper;
+using IMapper3 = ::android::hardware::graphics::mapper::V3_0::IMapper;
+
+using Error2 = ::android::hardware::graphics::mapper::V2_0::Error;
+using Error3 = ::android::hardware::graphics::mapper::V3_0::Error;
+
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
+using ::android::hardware::graphics::common::V1_0::PixelFormat;
+
+// This is a typedef to the same underlying type across v2.0 and v3.0
+using ::android::hardware::graphics::mapper::V2_0::BufferDescriptor;
+
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+
namespace android {
-GrallocWrapper::GrallocWrapper() {
- init();
+// Since we use the same APIs across allocator/mapper HALs but they have major
+// version differences (meaning they are not related through inheritance), we
+// create a common interface abstraction for the IAllocator + IMapper combination
+// (major versions need to match in the current HALs, e.g. IAllocator 3.0 needs to
+// be paired with IMapper 3.0, so these are tied together)
+class IGrallocHalWrapper {
+ public:
+ virtual ~IGrallocHalWrapper() = default;
+
+ // IAllocator
+ virtual std::string dumpDebugInfo() = 0;
+ virtual native_handle_t* allocate(uint32_t size) = 0;
+ virtual void freeBuffer(native_handle_t* bufferHandle) = 0;
+
+ // IMapper
+ virtual void* lock(native_handle_t* bufferHandle) = 0;
+ virtual void unlock(native_handle_t* bufferHandle) = 0;
+};
+
+namespace {
+
+bool failed(Error2 error) {
+ return (error != Error2::NONE);
+}
+bool failed(Error3 error) {
+ return (error != Error3::NONE);
}
-void GrallocWrapper::init() {
- mAllocator = allocator2::IAllocator::getService();
- if (mAllocator == nullptr) {
- ALOGE("Failed to get allocator service");
- }
-
- mMapper = mapper2::IMapper::getService();
- if (mMapper == nullptr) {
- ALOGE("Failed to get mapper service");
- }
- if (mMapper->isRemote()) {
- ALOGE("Mapper is not in passthrough mode");
- }
-}
-
-GrallocWrapper::~GrallocWrapper() {
- for (auto bufferHandle : mClonedBuffers) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
- native_handle_close(buffer);
- native_handle_delete(buffer);
- }
- mClonedBuffers.clear();
-
- for (auto bufferHandle : mImportedBuffers) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
- if (mMapper->freeBuffer(buffer) != mapper2::Error::NONE) {
- ALOGE("Failed to free buffer %p", buffer);
+// Since all the type and function names are the same for the things we use across the major HAL
+// versions, we use template magic to avoid repeating ourselves.
+template <typename AllocatorT, typename MapperT>
+class GrallocHalWrapper : public IGrallocHalWrapper {
+ public:
+ GrallocHalWrapper(const sp<AllocatorT>& allocator, const sp<MapperT>& mapper)
+ : mAllocator(allocator), mMapper(mapper) {
+ if (mapper->isRemote()) {
+ ALOGE("Mapper is in passthrough mode");
}
}
- mImportedBuffers.clear();
-}
-sp<allocator2::IAllocator> GrallocWrapper::getAllocator() const {
- return mAllocator;
-}
+ virtual std::string dumpDebugInfo() override;
+ virtual native_handle_t* allocate(uint32_t size) override;
+ virtual void freeBuffer(native_handle_t* bufferHandle) override;
-std::string GrallocWrapper::dumpDebugInfo() {
+ virtual void* lock(native_handle_t* bufferHandle) override;
+ virtual void unlock(native_handle_t* bufferHandle) override;
+
+ private:
+ static constexpr uint64_t kBufferUsage =
+ static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::CPU_READ_OFTEN);
+ sp<AllocatorT> mAllocator;
+ sp<MapperT> mMapper;
+
+ BufferDescriptor getDescriptor(uint32_t size);
+ native_handle_t* importBuffer(const hidl_handle& rawHandle);
+};
+
+template <typename AllocatorT, typename MapperT>
+std::string GrallocHalWrapper<AllocatorT, MapperT>::dumpDebugInfo() {
std::string debugInfo;
- mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
-
+ mAllocator->dumpDebugInfo([&](const hidl_string& tmpDebugInfo) { debugInfo = tmpDebugInfo; });
return debugInfo;
}
-const native_handle_t* GrallocWrapper::cloneBuffer(const hardware::hidl_handle& rawHandle) {
- const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
+template <typename AllocatorT, typename MapperT>
+native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::allocate(uint32_t size) {
+ constexpr uint32_t kBufferCount = 1;
+ BufferDescriptor descriptor = getDescriptor(size);
+ native_handle_t* bufferHandle = nullptr;
- if (bufferHandle) {
- mClonedBuffers.insert(bufferHandle);
- }
+ auto callback = [&](auto error, uint32_t /*stride*/, const hidl_vec<hidl_handle>& buffers) {
+ if (failed(error)) {
+ ALOGE("Failed to allocate buffer: %" PRId32, static_cast<int32_t>(error));
+ } else if (buffers.size() != kBufferCount) {
+ ALOGE("Invalid buffer array size (got %zu, expected %" PRIu32 ")", buffers.size(),
+ kBufferCount);
+ } else {
+ bufferHandle = importBuffer(buffers[0]);
+ }
+ };
+
+ mAllocator->allocate(descriptor, kBufferCount, callback);
return bufferHandle;
}
-std::vector<const native_handle_t*> GrallocWrapper::allocate(
- const mapper2::BufferDescriptor& descriptor, uint32_t count, bool import, uint32_t* outStride) {
- std::vector<const native_handle_t*> bufferHandles;
- bufferHandles.reserve(count);
- mAllocator->allocate(descriptor, count,
- [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
- if (mapper2::Error::NONE != tmpError) {
- ALOGE("Failed to allocate buffers");
- }
- if (count != tmpBuffers.size()) {
- ALOGE("Invalid buffer array");
- }
-
- for (uint32_t i = 0; i < count; i++) {
- if (import) {
- bufferHandles.push_back(importBuffer(tmpBuffers[i]));
- } else {
- bufferHandles.push_back(cloneBuffer(tmpBuffers[i]));
- }
- }
-
- if (outStride) {
- *outStride = tmpStride;
- }
- });
-
- return bufferHandles;
+template <typename AllocatorT, typename MapperT>
+void GrallocHalWrapper<AllocatorT, MapperT>::freeBuffer(native_handle_t* bufferHandle) {
+ auto error = mMapper->freeBuffer(bufferHandle);
+ if (!error.isOk() || failed(error)) {
+ ALOGE("Failed to free buffer %p", bufferHandle);
+ }
}
-const native_handle_t* GrallocWrapper::allocate(
- const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, bool import,
- uint32_t* outStride) {
- mapper2::BufferDescriptor descriptor = createDescriptor(descriptorInfo);
- auto buffers = allocate(descriptor, 1, import, outStride);
- return buffers[0];
-}
+template <typename AllocatorT, typename MapperT>
+BufferDescriptor GrallocHalWrapper<AllocatorT, MapperT>::getDescriptor(uint32_t size) {
+ typename MapperT::BufferDescriptorInfo descriptorInfo = {
+ .width = size,
+ .height = 1,
+ .layerCount = 1,
+ .usage = kBufferUsage,
+ .format = static_cast<decltype(descriptorInfo.format)>(PixelFormat::BLOB),
+ };
-sp<mapper2::IMapper> GrallocWrapper::getMapper() const {
- return mMapper;
-}
-
-mapper2::BufferDescriptor GrallocWrapper::createDescriptor(
- const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo) {
- mapper2::BufferDescriptor descriptor;
- mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
- if (tmpError != mapper2::Error::NONE) {
- ALOGE("Failed to create descriptor");
+ BufferDescriptor descriptor;
+ auto callback = [&](auto error, const BufferDescriptor& tmpDescriptor) {
+ if (failed(error)) {
+ ALOGE("Failed to create descriptor: %" PRId32, static_cast<int32_t>(error));
+ } else {
+ descriptor = tmpDescriptor;
}
- descriptor = tmpDescriptor;
- });
+ };
+ mMapper->createDescriptor(descriptorInfo, callback);
return descriptor;
}
-const native_handle_t* GrallocWrapper::importBuffer(const hardware::hidl_handle& rawHandle) {
- const native_handle_t* bufferHandle = nullptr;
- mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
- if (tmpError != mapper2::Error::NONE) {
- ALOGE("Failed to import buffer %p", rawHandle.getNativeHandle());
- }
- bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
- });
+template <typename AllocatorT, typename MapperT>
+native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::importBuffer(
+ const hidl_handle& rawHandle) {
+ native_handle_t* bufferHandle = nullptr;
- if (bufferHandle) {
- mImportedBuffers.insert(bufferHandle);
- }
+ mMapper->importBuffer(rawHandle, [&](auto error, void* tmpBuffer) {
+ if (failed(error)) {
+ ALOGE("Failed to import buffer %p: %" PRId32, rawHandle.getNativeHandle(),
+ static_cast<int32_t>(error));
+ } else {
+ bufferHandle = static_cast<native_handle_t*>(tmpBuffer);
+ }
+ });
return bufferHandle;
}
-void GrallocWrapper::freeBuffer(const native_handle_t* bufferHandle) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
-
- if (mImportedBuffers.erase(bufferHandle)) {
- mapper2::Error error = mMapper->freeBuffer(buffer);
- if (error != mapper2::Error::NONE) {
- ALOGE("Failed to free %p", buffer);
- }
- } else {
- mClonedBuffers.erase(bufferHandle);
- native_handle_close(buffer);
- native_handle_delete(buffer);
- }
-}
-
-void* GrallocWrapper::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
- const mapper2::IMapper::Rect& accessRegion, int acquireFence) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
-
- NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
- hardware::hidl_handle acquireFenceHandle;
- if (acquireFence >= 0) {
- auto h = native_handle_init(acquireFenceStorage, 1, 0);
- h->data[0] = acquireFence;
- acquireFenceHandle = h;
- }
+template <typename AllocatorT, typename MapperT>
+void* GrallocHalWrapper<AllocatorT, MapperT>::lock(native_handle_t* bufferHandle) {
+ // Per the HAL, all-zeros Rect means the entire buffer
+ typename MapperT::Rect accessRegion = {};
+ hidl_handle acquireFenceHandle; // No fence needed, already safe to lock
void* data = nullptr;
- mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpData) {
- if (tmpError != mapper2::Error::NONE) {
- ALOGE("Failed to lock buffer %p", buffer);
+ mMapper->lock(bufferHandle, kBufferUsage, accessRegion, acquireFenceHandle,
+ [&](auto error, void* tmpData, ...) { // V3_0 passes extra args we don't use
+ if (failed(error)) {
+ ALOGE("Failed to lock buffer %p: %" PRId32, bufferHandle,
+ static_cast<int32_t>(error));
+ } else {
+ data = tmpData;
}
- data = tmpData;
});
- if (acquireFence >= 0) {
- close(acquireFence);
- }
-
return data;
}
-int GrallocWrapper::unlock(const native_handle_t* bufferHandle) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
-
- int releaseFence = -1;
- mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
- if (tmpError != mapper2::Error::NONE) {
- ALOGE("Failed to unlock buffer %p", buffer);
- }
-
- auto fenceHandle = tmpReleaseFence.getNativeHandle();
- if (fenceHandle) {
- if (fenceHandle->numInts != 0) {
- ALOGE("Invalid fence handle %p", fenceHandle);
- }
- if (fenceHandle->numFds == 1) {
- releaseFence = dup(fenceHandle->data[0]);
- if (releaseFence < 0) {
- ALOGE("Failed to dup fence fd");
- }
- } else {
- if (fenceHandle->numFds != 0) {
- ALOGE("Invalid fence handle %p", fenceHandle);
- }
- }
+template <typename AllocatorT, typename MapperT>
+void GrallocHalWrapper<AllocatorT, MapperT>::unlock(native_handle_t* bufferHandle) {
+ mMapper->unlock(bufferHandle, [&](auto error, const hidl_handle& /*releaseFence*/) {
+ if (failed(error)) {
+ ALOGE("Failed to unlock buffer %p: %" PRId32, bufferHandle,
+ static_cast<int32_t>(error));
}
});
+}
- return releaseFence;
+} // anonymous namespace
+
+GrallocWrapper::GrallocWrapper() {
+ sp<IAllocator3> allocator3 = IAllocator3::getService();
+ sp<IMapper3> mapper3 = IMapper3::getService();
+
+ if (allocator3 != nullptr && mapper3 != nullptr) {
+ mGrallocHal = std::unique_ptr<IGrallocHalWrapper>(
+ new GrallocHalWrapper<IAllocator3, IMapper3>(allocator3, mapper3));
+ } else {
+ ALOGD("Graphics HALs 3.0 not found (allocator %d mapper %d), falling back to 2.x",
+ (allocator3 != nullptr), (mapper3 != nullptr));
+
+ sp<IAllocator2> allocator2 = IAllocator2::getService();
+ sp<IMapper2> mapper2 = IMapper2_1::getService();
+ if (mapper2 == nullptr) {
+ mapper2 = IMapper2::getService();
+ }
+
+ if (allocator2 != nullptr && mapper2 != nullptr) {
+ mGrallocHal = std::unique_ptr<IGrallocHalWrapper>(
+ new GrallocHalWrapper<IAllocator2, IMapper2>(allocator2, mapper2));
+ } else {
+ ALOGE("Couldn't open 2.x/3.0 graphics HALs (2.x allocator %d mapper %d)",
+ (allocator2 != nullptr), (mapper2 != nullptr));
+ }
+ }
+}
+
+GrallocWrapper::~GrallocWrapper() {
+ for (auto bufferHandle : mAllocatedBuffers) {
+ mGrallocHal->unlock(bufferHandle);
+ mGrallocHal->freeBuffer(bufferHandle);
+ }
+ mAllocatedBuffers.clear();
+}
+
+std::string GrallocWrapper::dumpDebugInfo() {
+ return mGrallocHal->dumpDebugInfo();
+}
+
+std::pair<native_handle_t*, void*> GrallocWrapper::allocate(uint32_t size) {
+ native_handle_t* bufferHandle = mGrallocHal->allocate(size);
+ void* buffer = nullptr;
+ if (bufferHandle) {
+ buffer = mGrallocHal->lock(bufferHandle);
+ if (buffer) {
+ mAllocatedBuffers.insert(bufferHandle);
+ } else {
+ mGrallocHal->freeBuffer(bufferHandle);
+ bufferHandle = nullptr;
+ }
+ }
+ return std::make_pair<>(bufferHandle, buffer);
+}
+
+void GrallocWrapper::freeBuffer(native_handle_t* bufferHandle) {
+ if (mAllocatedBuffers.erase(bufferHandle)) {
+ mGrallocHal->unlock(bufferHandle);
+ mGrallocHal->freeBuffer(bufferHandle);
+ }
}
} // namespace android
diff --git a/sensors/common/vts/utils/SensorsTestSharedMemory.cpp b/sensors/common/vts/utils/SensorsTestSharedMemory.cpp
index 819e297..3b068bd 100644
--- a/sensors/common/vts/utils/SensorsTestSharedMemory.cpp
+++ b/sensors/common/vts/utils/SensorsTestSharedMemory.cpp
@@ -119,32 +119,13 @@
}
case SharedMemType::GRALLOC: {
mGrallocWrapper = std::make_unique<::android::GrallocWrapper>();
- if (mGrallocWrapper->getAllocator() == nullptr ||
- mGrallocWrapper->getMapper() == nullptr) {
+ if (!mGrallocWrapper->isInitialized()) {
break;
}
- using android::hardware::graphics::common::V1_0::BufferUsage;
- using android::hardware::graphics::common::V1_0::PixelFormat;
- mapper2::IMapper::BufferDescriptorInfo buf_desc_info = {
- .width = static_cast<uint32_t>(size),
- .height = 1,
- .layerCount = 1,
- .usage = static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA |
- BufferUsage::CPU_READ_OFTEN),
- .format = PixelFormat::BLOB};
- handle = const_cast<native_handle_t*>(mGrallocWrapper->allocate(buf_desc_info));
- if (handle != nullptr) {
- mapper2::IMapper::Rect region{0, 0, static_cast<int32_t>(buf_desc_info.width),
- static_cast<int32_t>(buf_desc_info.height)};
- buffer = static_cast<char*>(
- mGrallocWrapper->lock(handle, buf_desc_info.usage, region, /*fence=*/-1));
- if (buffer != nullptr) {
- break;
- }
- mGrallocWrapper->freeBuffer(handle);
- handle = nullptr;
- }
+ std::pair<native_handle_t*, void*> buf = mGrallocWrapper->allocate(size);
+ handle = buf.first;
+ buffer = static_cast<char*>(buf.second);
break;
}
default:
@@ -175,9 +156,7 @@
}
case SharedMemType::GRALLOC: {
if (mSize != 0) {
- mGrallocWrapper->unlock(mNativeHandle);
mGrallocWrapper->freeBuffer(mNativeHandle);
-
mNativeHandle = nullptr;
mSize = 0;
}
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h b/sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h
index 3bd73c3..41e6334 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h
@@ -14,66 +14,47 @@
* limitations under the License.
*/
-#ifndef GRALLO_WRAPPER_H_
-#define GRALLO_WRAPPER_H_
+#pragma once
+#include <utils/NativeHandle.h>
+
+#include <memory>
+#include <string>
#include <unordered_set>
-
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-
-namespace allocator2 = ::android::hardware::graphics::allocator::V2_0;
-namespace mapper2 = ::android::hardware::graphics::mapper::V2_0;
+#include <utility>
namespace android {
-// Modified from hardware/interfaces/graphics/mapper/2.0/vts/functional/
+class IGrallocHalWrapper;
+
+// Reference: hardware/interfaces/graphics/mapper/2.0/vts/functional/
class GrallocWrapper {
public:
GrallocWrapper();
~GrallocWrapper();
- sp<allocator2::IAllocator> getAllocator() const;
- sp<mapper2::IMapper> getMapper() const;
+ // After constructing this object, this function must be called to check the result. If it
+ // returns false, other methods are not safe to call.
+ bool isInitialized() const { return (mGrallocHal != nullptr); };
std::string dumpDebugInfo();
- // When import is false, this simply calls IAllocator::allocate. When import
- // is true, the returned buffers are also imported into the mapper.
- //
- // Either case, the returned buffers must be freed with freeBuffer.
- std::vector<const native_handle_t*> allocate(const mapper2::BufferDescriptor& descriptor,
- uint32_t count, bool import = true,
- uint32_t* outStride = nullptr);
- const native_handle_t* allocate(const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo,
- bool import = true, uint32_t* outStride = nullptr);
+ // Allocates a gralloc buffer suitable for direct channel sensors usage with the given size.
+ // The buffer should be freed using freeBuffer when it's not needed anymore; otherwise it'll
+ // be freed when this object is destroyed.
+ // Returns a handle to the buffer, and a CPU-accessible pointer for reading. On failure, both
+ // will be set to nullptr.
+ std::pair<native_handle_t*, void*> allocate(uint32_t size);
- mapper2::BufferDescriptor createDescriptor(
- const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo);
+ // Releases a gralloc buffer previously returned by allocate()
+ void freeBuffer(native_handle_t* bufferHandle);
- const native_handle_t* importBuffer(const hardware::hidl_handle& rawHandle);
- void freeBuffer(const native_handle_t* bufferHandle);
-
- // We use fd instead of hardware::hidl_handle in these functions to pass fences
- // in and out of the mapper. The ownership of the fd is always transferred
- // with each of these functions.
- void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
- const mapper2::IMapper::Rect& accessRegion, int acquireFence);
-
- int unlock(const native_handle_t* bufferHandle);
-
- private:
- void init();
- const native_handle_t* cloneBuffer(const hardware::hidl_handle& rawHandle);
-
- sp<allocator2::IAllocator> mAllocator;
- sp<mapper2::IMapper> mMapper;
+ private:
+ std::unique_ptr<IGrallocHalWrapper> mGrallocHal;
// Keep track of all cloned and imported handles. When a test fails with
// ASSERT_*, the destructor will free the handles for the test.
- std::unordered_set<const native_handle_t*> mClonedBuffers;
- std::unordered_set<const native_handle_t*> mImportedBuffers;
+ std::unordered_set<native_handle_t*> mAllocatedBuffers;
};
} // namespace android
-#endif // GRALLO_WRAPPER_H_