[automerger skipped] DO NOT MERGE: audio: Skip tests if audio HAL service lacks "primary" device
am: 1ed70316c5 -s ours
am skip reason: subject contains skip directive
Change-Id: Idb5bb585dc22bd6027f1177bbb90392aad464d4b
diff --git a/audio/4.0/config/audio_policy_configuration.xsd b/audio/4.0/config/audio_policy_configuration.xsd
index f26e41b..58bab22 100644
--- a/audio/4.0/config/audio_policy_configuration.xsd
+++ b/audio/4.0/config/audio_policy_configuration.xsd
@@ -357,10 +357,6 @@
<xs:enumeration value="AUDIO_FORMAT_APTX_HD"/>
<xs:enumeration value="AUDIO_FORMAT_AC4"/>
<xs:enumeration value="AUDIO_FORMAT_LDAC"/>
- <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/>
- <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
- <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/>
- <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="extendableAudioFormat">
diff --git a/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc b/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc
index 8217b94..6e91bcc 100644
--- a/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc
+++ b/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc
@@ -2,7 +2,8 @@
class hal
user audioserver
# media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
- group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct
+ group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock
+ capabilities BLOCK_SUSPEND
ioprio rt 4
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
# audioflinger restarts itself when it loses connection with the hal
diff --git a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index 545d6c0..46c228a 100644
--- a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -155,11 +155,6 @@
protected:
// Cache the devicesFactory retrieval to speed up each test by ~0.5s
static sp<IDevicesFactory> devicesFactory;
-
- static bool isPrimaryDeviceOptional() {
- // It's OK not to have "primary" device on non-default audio HAL service.
- return environment->getServiceName<IDevicesFactory>() != kDefaultServiceName;
- }
};
sp<IDevicesFactory> AudioHidlTest::devicesFactory;
@@ -176,7 +171,19 @@
ASSERT_TRUE(device == nullptr);
}
-static void waitForDeviceDestruction() {
+TEST_F(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
+ doc::test("Calling openDevice(\"primary\") should return the primary device.");
+ {
+ Result result;
+ sp<IDevice> baseDevice;
+ ASSERT_OK(devicesFactory->openDevice("primary", returnIn(result, baseDevice)));
+ ASSERT_OK(result);
+ ASSERT_TRUE(baseDevice != nullptr);
+
+ Return<sp<IPrimaryDevice>> primaryDevice = IPrimaryDevice::castFrom(baseDevice);
+ ASSERT_TRUE(primaryDevice.isOk());
+ ASSERT_TRUE(sp<IPrimaryDevice>(primaryDevice) != nullptr);
+ } // Destroy local IDevice proxy
// FIXME: there is no way to know when the remote IDevice is being destroyed
// Binder does not support testing if an object is alive, thus
// wait for 100ms to let the binder destruction propagates and
@@ -184,26 +191,7 @@
// flushCommand makes sure all local command are sent, thus should reduce
// the latency between local and remote destruction.
IPCThreadState::self()->flushCommands();
- usleep(100*1000);
-}
-
-TEST_F(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
- doc::test("Calling openDevice(\"primary\") should return the primary device.");
- struct WaitExecutor {
- ~WaitExecutor() { waitForDeviceDestruction(); }
- } waitExecutor; // Make sure we wait for the device destruction on exiting from the test.
- Result result;
- sp<IDevice> baseDevice;
- ASSERT_OK(devicesFactory->openDevice("primary", returnIn(result, baseDevice)));
- if (result != Result::OK && isPrimaryDeviceOptional()) {
- return SUCCEED() << "No primary device on this factory";
- }
- ASSERT_OK(result);
- ASSERT_TRUE(baseDevice != nullptr);
-
- Return<sp<IPrimaryDevice>> primaryDevice = IPrimaryDevice::castFrom(baseDevice);
- ASSERT_TRUE(primaryDevice.isOk());
- ASSERT_TRUE(sp<IPrimaryDevice>(primaryDevice) != nullptr);
+ usleep(100);
}
//////////////////////////////////////////////////////////////////////////////
@@ -216,44 +204,29 @@
/** Primary HAL test are NOT thread safe. */
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp()); // setup base
+
if (device == nullptr) {
- initPrimaryDevice();
- if (device == nullptr && isPrimaryDeviceOptional()) {
- return SUCCEED() << "No primary device on this factory";
- }
+ Result result;
+ ASSERT_OK(devicesFactory->openPrimaryDevice(returnIn(result, device)));
+ ASSERT_OK(result);
+ ASSERT_TRUE(device != nullptr);
+
+ environment->registerTearDown([] { device.clear(); });
}
- ASSERT_TRUE(device != nullptr);
}
protected:
// Cache the device opening to speed up each test by ~0.5s
static sp<IPrimaryDevice> device;
-
- static void initPrimaryDevice() {
- ASSERT_TRUE(devicesFactory != nullptr);
- Result result;
- ASSERT_OK(devicesFactory->openPrimaryDevice(returnIn(result, device)));
- ASSERT_OK(result);
- if (device != nullptr) {
- environment->registerTearDown([] { device.clear(); });
- }
- }
};
sp<IPrimaryDevice> AudioPrimaryHidlTest::device;
-#define SKIP_IF_NO_DEVICE \
- if (!device) { \
- doc::partialTest("No primary device on this factory"); \
- return; \
- } \
-
TEST_F(AudioPrimaryHidlTest, OpenPrimaryDevice) {
doc::test("Test the openDevice (called in SetUp)");
}
TEST_F(AudioPrimaryHidlTest, Init) {
doc::test("Test that the audio primary hal initialized correctly");
- SKIP_IF_NO_DEVICE;
ASSERT_OK(device->initCheck());
}
@@ -277,7 +250,6 @@
void testAccessors(const string& propertyName, const Initial expectedInitial,
list<Property> valuesToTest, Setter setter, Getter getter,
const vector<Property>& invalidValues = {}) {
- SKIP_IF_NO_DEVICE;
const auto expectedResults = {Result::OK,
optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK};
@@ -360,7 +332,6 @@
TEST_F(AudioPatchPrimaryHidlTest, AudioPatches) {
doc::test("Test if audio patches are supported");
- SKIP_IF_NO_DEVICE;
if (!areAudioPatchesSupported()) {
doc::partialTest("Audio patches are not supported");
return;
@@ -460,7 +431,6 @@
public ::testing::WithParamInterface<AudioConfig> {
protected:
void inputBufferSizeTest(const AudioConfig& audioConfig, bool supportRequired) {
- SKIP_IF_NO_DEVICE;
uint64_t bufferSize;
ASSERT_OK(device->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
@@ -517,7 +487,6 @@
TEST_F(AudioPrimaryHidlTest, setScreenState) {
doc::test("Check that the hal can receive the screen state");
- SKIP_IF_NO_DEVICE;
for (bool turnedOn : {false, true, true, false, false}) {
ASSERT_RESULT(okOrNotSupported, device->setScreenState(turnedOn));
}
@@ -529,7 +498,6 @@
TEST_F(AudioPrimaryHidlTest, getParameters) {
doc::test("Check that the hal can set and get parameters");
- SKIP_IF_NO_DEVICE;
hidl_vec<ParameterValue> context;
hidl_vec<hidl_string> keys;
hidl_vec<ParameterValue> values;
@@ -545,7 +513,6 @@
TEST_F(AudioPrimaryHidlTest, GetMicrophonesTest) {
doc::test("Make sure getMicrophones always succeeds");
- SKIP_IF_NO_DEVICE;
hidl_vec<MicrophoneInfo> microphones;
ASSERT_OK(device->getMicrophones(returnIn(res, microphones)));
ASSERT_OK(res);
@@ -661,19 +628,16 @@
TEST_F(AudioPrimaryHidlTest, DebugDump) {
doc::test("Check that the hal can dump its state without error");
- SKIP_IF_NO_DEVICE;
testDebugDump([](const auto& handle) { return device->debug(handle, {/* options */}); });
}
TEST_F(AudioPrimaryHidlTest, DebugDumpInvalidArguments) {
doc::test("Check that the hal dump doesn't crash on invalid arguments");
- SKIP_IF_NO_DEVICE;
ASSERT_OK(device->debug(hidl_handle(), {/* options */}));
}
TEST_F(AudioPrimaryHidlTest, SetConnectedState) {
doc::test("Check that the HAL can be notified of device connection and deconnection");
- SKIP_IF_NO_DEVICE;
using AD = AudioDevice;
for (auto deviceType : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
SCOPED_TRACE("device=" + ::testing::PrintToString(deviceType));
@@ -690,13 +654,6 @@
ASSERT_OK(ret);
}
}
-
- // Because there is no way of knowing if the devices were connected before
- // calling setConnectedState, there is no way to restore the HAL to its
- // initial state. To workaround this, destroy the HAL at the end of this test.
- device.clear();
- waitForDeviceDestruction();
- ASSERT_NO_FATAL_FAILURE(initPrimaryDevice());
}
//////////////////////////////////////////////////////////////////////////////
@@ -709,7 +666,6 @@
protected:
template <class Open>
void testOpen(Open openStream, const AudioConfig& config) {
- SKIP_IF_NO_DEVICE;
// FIXME: Open a stream without an IOHandle
// This is not required to be accepted by hal implementations
AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
@@ -742,29 +698,14 @@
Return<Result> closeStream() {
open = false;
- auto res = stream->close();
- stream.clear();
- waitForStreamDestruction();
- return res;
- }
-
- void waitForStreamDestruction() {
- // FIXME: there is no way to know when the remote IStream is being destroyed
- // Binder does not support testing if an object is alive, thus
- // wait for 100ms to let the binder destruction propagates and
- // the remote device has the time to be destroyed.
- // flushCommand makes sure all local command are sent, thus should reduce
- // the latency between local and remote destruction.
- IPCThreadState::self()->flushCommands();
- usleep(100*1000);
+ return stream->close();
}
private:
void TearDown() override {
if (open) {
- ASSERT_OK(closeStream());
+ ASSERT_OK(stream->close());
}
- AudioConfigPrimaryTest::TearDown();
}
protected:
@@ -777,9 +718,8 @@
////////////////////////////// openOutputStream //////////////////////////////
class OutputStreamTest : public OpenStreamTest<IStreamOut> {
- void SetUp() override {
+ virtual void SetUp() override {
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
- if (!device && !HasFailure()) return; // do not attempt to use 'device'
address.device = AudioDevice::OUT_DEFAULT;
const AudioConfig& config = GetParam();
// TODO: test all flag combination
@@ -819,9 +759,8 @@
////////////////////////////// openInputStream //////////////////////////////
class InputStreamTest : public OpenStreamTest<IStreamIn> {
- void SetUp() override {
+ virtual void SetUp() override {
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
- if (!device && !HasFailure()) return; // do not attempt to use 'device'
address.device = AudioDevice::IN_DEFAULT;
const AudioConfig& config = GetParam();
// TODO: test all supported flags and source
@@ -872,23 +811,15 @@
return ret;
}
-#define SKIP_IF_NO_STREAM \
- if (!stream) { \
- doc::partialTest("No primary device on this factory"); \
- return; \
- }
-
/* Could not find a way to write a test for two parametrized class fixure
* thus use this macro do duplicate tests for Input and Output stream */
#define TEST_IO_STREAM(test_name, documentation, code) \
TEST_P(InputStreamTest, test_name) { \
doc::test(documentation); \
- SKIP_IF_NO_STREAM; \
code; \
} \
TEST_P(OutputStreamTest, test_name) { \
doc::test(documentation); \
- SKIP_IF_NO_STREAM; \
code; \
}
@@ -917,7 +848,6 @@
Return<Property> (IStream::*getter)(),
Return<Result> (IStream::*setter)(Property),
bool currentMustBeSupported = true) {
- SKIP_IF_NO_STREAM;
hidl_vec<Property> capabilities;
auto ret = capablityGetter(stream, capabilities);
if (ret == Result::NOT_SUPPORTED) {
@@ -987,7 +917,6 @@
&IStream::getFormat, &IStream::setFormat))
static void testGetDevices(IStream* stream, AudioDevice expectedDevice) {
- SKIP_IF_NO_STREAM;
hidl_vec<DeviceAddress> devices;
Result res;
ASSERT_OK(stream->getDevices(returnIn(res, devices)));
@@ -1007,7 +936,6 @@
: testGetDevices(stream.get(), address.device))
static void testSetDevices(IStream* stream, const DeviceAddress& address) {
- SKIP_IF_NO_STREAM;
DeviceAddress otherAddress = address;
otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 ? AudioDevice::OUT_SPEAKER
: AudioDevice::IN_BUILTIN_MIC;
@@ -1021,7 +949,6 @@
: testSetDevices(stream.get(), address))
static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
- SKIP_IF_NO_STREAM;
uint32_t sampleRateHz;
hidl_bitfield<AudioChannelMask> mask;
AudioFormat format;
@@ -1043,7 +970,6 @@
ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, stream->setHwAvSync(666)))
static void checkGetHwAVSync(IDevice* device) {
- SKIP_IF_NO_DEVICE;
Result res;
AudioHwSync sync;
ASSERT_OK(device->getHwAvSync(returnIn(res, sync)));
@@ -1056,7 +982,6 @@
static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
initializer_list<Result> expectedResults) {
- SKIP_IF_NO_STREAM;
hidl_vec<ParameterValue> context;
hidl_vec<ParameterValue> parameters;
Result res;
@@ -1126,15 +1051,10 @@
ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream()))
-TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
- auto streamCopy = stream;
- ASSERT_OK(closeStream());
- ASSERT_RESULT(Result::INVALID_STATE, streamCopy->close());
- streamCopy.clear();
- waitForStreamDestruction())
+TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice", ASSERT_OK(closeStream());
+ ASSERT_RESULT(Result::INVALID_STATE, closeStream()))
static void testCreateTooBigMmapBuffer(IStream* stream) {
- SKIP_IF_NO_STREAM;
MmapBufferInfo info;
Result res;
// Assume that int max is a value too big to be allocated
@@ -1149,7 +1069,6 @@
testCreateTooBigMmapBuffer(stream.get()))
static void testGetMmapPositionOfNonMmapedStream(IStream* stream) {
- SKIP_IF_NO_STREAM;
Result res;
MmapPosition position;
ASSERT_OK(stream->getMmapPosition(returnIn(res, position)));
@@ -1166,7 +1085,6 @@
TEST_P(InputStreamTest, GetAudioSource) {
doc::test("Retrieving the audio source of an input stream should always succeed");
- SKIP_IF_NO_STREAM;
AudioSource source;
ASSERT_OK(stream->getAudioSource(returnIn(res, source)));
if (res == Result::NOT_SUPPORTED) {
@@ -1201,14 +1119,12 @@
TEST_P(InputStreamTest, SetGain) {
doc::test("The gain of an input stream should only be set between [0,1]");
- SKIP_IF_NO_STREAM;
testOptionalUnitaryGain([this](float volume) { return stream->setGain(volume); },
"InputStream::setGain");
}
static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, uint32_t framesCount) {
Result res;
- SKIP_IF_NO_STREAM;
// Ignore output parameters as the call should fail
ASSERT_OK(stream->prepareForReading(frameSize, framesCount,
[&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
@@ -1217,13 +1133,11 @@
TEST_P(InputStreamTest, PrepareForReadingWithZeroBuffer) {
doc::test("Preparing a stream for reading with a 0 sized buffer should fail");
- SKIP_IF_NO_STREAM;
testPrepareForReading(stream.get(), 0, 0);
}
TEST_P(InputStreamTest, PrepareForReadingWithHugeBuffer) {
doc::test("Preparing a stream for reading with a 2^32 sized buffer should fail");
- SKIP_IF_NO_STREAM;
testPrepareForReading(stream.get(), 1, std::numeric_limits<uint32_t>::max());
}
@@ -1231,14 +1145,12 @@
doc::test(
"Preparing a stream for reading with a overflowing sized buffer should "
"fail");
- SKIP_IF_NO_STREAM;
auto uintMax = std::numeric_limits<uint32_t>::max();
testPrepareForReading(stream.get(), uintMax, uintMax);
}
TEST_P(InputStreamTest, GetInputFramesLost) {
doc::test("The number of frames lost on a never started stream should be 0");
- SKIP_IF_NO_STREAM;
auto ret = stream->getInputFramesLost();
ASSERT_IS_OK(ret);
uint32_t framesLost{ret};
@@ -1249,7 +1161,6 @@
doc::test(
"The capture position of a non prepared stream should not be "
"retrievable or 0");
- SKIP_IF_NO_STREAM;
uint64_t frames;
uint64_t time;
ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time)));
@@ -1262,7 +1173,6 @@
TEST_P(InputStreamTest, updateSinkMetadata) {
doc::test("The HAL should not crash on metadata change");
- SKIP_IF_NO_STREAM;
hidl_enum_iterator<AudioSource> range;
// Test all possible track configuration
@@ -1289,7 +1199,6 @@
TEST_P(OutputStreamTest, getLatency) {
doc::test("Make sure latency is over 0");
- SKIP_IF_NO_STREAM;
auto result = stream->getLatency();
ASSERT_IS_OK(result);
ASSERT_GT(result, 0U);
@@ -1297,14 +1206,12 @@
TEST_P(OutputStreamTest, setVolume) {
doc::test("Try to set the output volume");
- SKIP_IF_NO_STREAM;
testOptionalUnitaryGain([this](float volume) { return stream->setVolume(volume, volume); },
"setVolume");
}
static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32_t framesCount) {
Result res;
- SKIP_IF_NO_STREAM;
// Ignore output parameters as the call should fail
ASSERT_OK(stream->prepareForWriting(frameSize, framesCount,
[&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
@@ -1313,13 +1220,11 @@
TEST_P(OutputStreamTest, PrepareForWriteWithZeroBuffer) {
doc::test("Preparing a stream for writing with a 0 sized buffer should fail");
- SKIP_IF_NO_STREAM;
testPrepareForWriting(stream.get(), 0, 0);
}
TEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) {
doc::test("Preparing a stream for writing with a 2^32 sized buffer should fail");
- SKIP_IF_NO_STREAM;
testPrepareForWriting(stream.get(), 1, std::numeric_limits<uint32_t>::max());
}
@@ -1327,7 +1232,6 @@
doc::test(
"Preparing a stream for writing with a overflowing sized buffer should "
"fail");
- SKIP_IF_NO_STREAM;
auto uintMax = std::numeric_limits<uint32_t>::max();
testPrepareForWriting(stream.get(), uintMax, uintMax);
}
@@ -1348,7 +1252,6 @@
TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) {
doc::test("Implementation must expose pause, resume and drain capabilities");
- SKIP_IF_NO_STREAM;
Capability(stream.get());
}
@@ -1367,7 +1270,6 @@
TEST_P(OutputStreamTest, GetRenderPosition) {
doc::test("A new stream render position should be 0 or INVALID_STATE");
- SKIP_IF_NO_STREAM;
uint32_t dspFrames;
ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames)));
if (res == Result::NOT_SUPPORTED) {
@@ -1379,7 +1281,6 @@
TEST_P(OutputStreamTest, GetNextWriteTimestamp) {
doc::test("A new stream next write timestamp should be 0 or INVALID_STATE");
- SKIP_IF_NO_STREAM;
uint64_t timestampUs;
ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs)));
if (res == Result::NOT_SUPPORTED) {
@@ -1397,7 +1298,6 @@
};
static bool isAsyncModeSupported(IStreamOut* stream) {
- if (!stream) return false;
auto res = stream->setCallback(new MockOutCallbacks);
stream->clearCallback(); // try to restore the no callback state, ignore
// any error
@@ -1434,7 +1334,6 @@
doc::test(
"If supported, a stream should fail to resume if not previously "
"paused");
- SKIP_IF_NO_STREAM;
if (!Capability(stream.get()).resume) {
doc::partialTest("The output stream does not support resume");
return;
@@ -1446,7 +1345,6 @@
doc::test(
"If supported, a stream should fail to pause if not previously "
"started");
- SKIP_IF_NO_STREAM;
if (!Capability(stream.get()).pause) {
doc::partialTest("The output stream does not support pause");
return;
@@ -1464,19 +1362,16 @@
TEST_P(OutputStreamTest, DrainAll) {
doc::test("If supported, a stream should always succeed to drain");
- SKIP_IF_NO_STREAM;
testDrain(stream.get(), AudioDrain::ALL);
}
TEST_P(OutputStreamTest, DrainEarlyNotify) {
doc::test("If supported, a stream should always succeed to drain");
- SKIP_IF_NO_STREAM;
testDrain(stream.get(), AudioDrain::EARLY_NOTIFY);
}
TEST_P(OutputStreamTest, FlushStop) {
doc::test("If supported, a stream should always succeed to flush");
- SKIP_IF_NO_STREAM;
auto ret = stream->flush();
ASSERT_IS_OK(ret);
if (ret == Result::NOT_SUPPORTED) {
@@ -1490,7 +1385,6 @@
doc::test(
"If supported, a stream should always succeed to retrieve the "
"presentation position");
- SKIP_IF_NO_STREAM;
uint64_t frames;
TimeSpec mesureTS;
ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS)));
@@ -1518,13 +1412,11 @@
TEST_P(OutputStreamTest, SelectPresentation) {
doc::test("Verify that presentation selection does not crash");
- SKIP_IF_NO_STREAM;
ASSERT_RESULT(okOrNotSupported, stream->selectPresentation(0, 0));
}
TEST_P(OutputStreamTest, updateSourceMetadata) {
doc::test("The HAL should not crash on metadata change");
- SKIP_IF_NO_STREAM;
hidl_enum_iterator<AudioUsage> usageRange;
hidl_enum_iterator<AudioContentType> contentRange;
@@ -1560,13 +1452,11 @@
TEST_F(AudioPrimaryHidlTest, setVoiceVolume) {
doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]");
- SKIP_IF_NO_DEVICE;
testUnitaryGain([](float volume) { return device->setVoiceVolume(volume); });
}
TEST_F(AudioPrimaryHidlTest, setMode) {
doc::test("Make sure setMode always succeeds if mode is valid and fails otherwise");
- SKIP_IF_NO_DEVICE;
// Test Invalid values
for (int mode : {-2, -1, int(AudioMode::IN_COMMUNICATION) + 1}) {
ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(AudioMode(mode)))
@@ -1583,7 +1473,6 @@
doc::test(
"Make sure setBtHfpSampleRate either succeeds or "
"indicates that it is not supported at all, or that the provided value is invalid");
- SKIP_IF_NO_DEVICE;
for (auto samplingRate : {8000, 16000, 22050, 24000}) {
ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, device->setBtHfpSampleRate(samplingRate));
}
@@ -1593,7 +1482,6 @@
doc::test(
"Make sure setBtHfpVolume is either not supported or "
"only succeed if volume is in [0,1]");
- SKIP_IF_NO_DEVICE;
auto ret = device->setBtHfpVolume(0.0);
ASSERT_TRUE(ret.isOk());
if (ret == Result::NOT_SUPPORTED) {
@@ -1607,13 +1495,11 @@
doc::test(
"Make sure setBtScoHeadsetDebugName either succeeds or "
"indicates that it is not supported");
- SKIP_IF_NO_DEVICE;
ASSERT_RESULT(okOrNotSupported, device->setBtScoHeadsetDebugName("test"));
}
TEST_F(AudioPrimaryHidlTest, updateRotation) {
doc::test("Check that the hal can receive the current rotation");
- SKIP_IF_NO_DEVICE;
for (Rotation rotation : {Rotation::DEG_0, Rotation::DEG_90, Rotation::DEG_180,
Rotation::DEG_270, Rotation::DEG_0}) {
ASSERT_RESULT(okOrNotSupported, device->updateRotation(rotation));
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 69f8535..fd785df 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -53,6 +53,7 @@
camera3_callback_ops({&sProcessCaptureResult, &sNotify}),
mDevice(device),
mDeviceVersion(device->common.version),
+ mFreeBufEarly(shouldFreeBufEarly()),
mIsAELockAvailable(false),
mDerivePostRawSensKey(false),
mNumPartialResults(1),
@@ -129,6 +130,10 @@
return false;
}
+bool CameraDeviceSession::shouldFreeBufEarly() {
+ return property_get_bool("ro.vendor.camera.free_buf_early", 0) == 1;
+}
+
CameraDeviceSession::~CameraDeviceSession() {
if (!isClosed()) {
ALOGE("CameraDeviceSession deleted before close!");
@@ -887,6 +892,24 @@
(*streams)[i] = &mStreamMap[id];
}
+ if (mFreeBufEarly) {
+ // Remove buffers of deleted streams
+ for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+ int id = it->first;
+ bool found = false;
+ for (const auto& stream : requestedConfiguration.streams) {
+ if (id == stream.id) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // Unmap all buffers of deleted stream
+ cleanupBuffersLocked(id);
+ }
+ }
+ }
+
return true;
}
@@ -908,7 +931,9 @@
// Unmap all buffers of deleted stream
// in case the configuration call succeeds and HAL
// is able to release the corresponding resources too.
- cleanupBuffersLocked(id);
+ if (!mFreeBufEarly) {
+ cleanupBuffersLocked(id);
+ }
it = mStreamMap.erase(it);
} else {
++it;
@@ -927,6 +952,27 @@
mResultBatcher.setBatchedStreams(mVideoStreamIds);
}
+
+void CameraDeviceSession::postProcessConfigurationFailureLocked(
+ const StreamConfiguration& requestedConfiguration) {
+ if (mFreeBufEarly) {
+ // Re-build the buf cache entry for deleted streams
+ for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+ int id = it->first;
+ bool found = false;
+ for (const auto& stream : requestedConfiguration.streams) {
+ if (id == stream.id) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ mCirculatingBuffers.emplace(id, CirculatingBuffers{});
+ }
+ }
+ }
+}
+
Return<void> CameraDeviceSession::configureStreams(
const StreamConfiguration& requestedConfiguration,
ICameraDeviceSession::configureStreams_cb _hidl_cb) {
@@ -979,6 +1025,8 @@
// the corresponding resources of the deleted streams.
if (ret == OK) {
postProcessConfigurationLocked(requestedConfiguration);
+ } else {
+ postProcessConfigurationFailureLocked(requestedConfiguration);
}
if (ret == -EINVAL) {
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index af90e5a..bcee259 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -120,6 +120,8 @@
hidl_vec<camera3_stream_t*> *streams /*out*/);
void postProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration);
+ void postProcessConfigurationFailureLocked(const StreamConfiguration& requestedConfiguration);
+
protected:
// protecting mClosed/mDisconnected/mInitFail
@@ -142,6 +144,7 @@
camera3_device_t* mDevice;
const uint32_t mDeviceVersion;
+ const bool mFreeBufEarly;
bool mIsAELockAvailable;
bool mDerivePostRawSensKey;
uint32_t mNumPartialResults;
@@ -293,6 +296,8 @@
bool initialize();
+ static bool shouldFreeBufEarly();
+
Status initStatus() const;
// Validate and import request's input buffer and acquire fence
diff --git a/camera/device/3.3/default/CameraDeviceSession.cpp b/camera/device/3.3/default/CameraDeviceSession.cpp
index d36e9ed..60174fb 100644
--- a/camera/device/3.3/default/CameraDeviceSession.cpp
+++ b/camera/device/3.3/default/CameraDeviceSession.cpp
@@ -92,6 +92,8 @@
// the corresponding resources of the deleted streams.
if (ret == OK) {
postProcessConfigurationLocked(requestedConfiguration);
+ } else {
+ postProcessConfigurationFailureLocked(requestedConfiguration);
}
if (ret == -EINVAL) {
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index 6a18161..f2e031c 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -154,6 +154,8 @@
// the corresponding resources of the deleted streams.
if (ret == OK) {
postProcessConfigurationLocked_3_4(requestedConfiguration);
+ } else {
+ postProcessConfigurationFailureLocked_3_4(requestedConfiguration);
}
if (ret == -EINVAL) {
@@ -215,6 +217,23 @@
(*streams)[i] = &mStreamMap[id];
}
+ if (mFreeBufEarly) {
+ // Remove buffers of deleted streams
+ for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+ int id = it->first;
+ bool found = false;
+ for (const auto& stream : requestedConfiguration.streams) {
+ if (id == stream.v3_2.id) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // Unmap all buffers of deleted stream
+ cleanupBuffersLocked(id);
+ }
+ }
+ }
return true;
}
@@ -236,7 +255,9 @@
// Unmap all buffers of deleted stream
// in case the configuration call succeeds and HAL
// is able to release the corresponding resources too.
- cleanupBuffersLocked(id);
+ if (!mFreeBufEarly) {
+ cleanupBuffersLocked(id);
+ }
it = mStreamMap.erase(it);
} else {
++it;
@@ -255,6 +276,26 @@
mResultBatcher_3_4.setBatchedStreams(mVideoStreamIds);
}
+void CameraDeviceSession::postProcessConfigurationFailureLocked_3_4(
+ const StreamConfiguration& requestedConfiguration) {
+ if (mFreeBufEarly) {
+ // Re-build the buf cache entry for deleted streams
+ for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+ int id = it->first;
+ bool found = false;
+ for (const auto& stream : requestedConfiguration.streams) {
+ if (id == stream.v3_2.id) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ mCirculatingBuffers.emplace(id, CirculatingBuffers{});
+ }
+ }
+ }
+}
+
Return<void> CameraDeviceSession::processCaptureRequest_3_4(
const hidl_vec<V3_4::CaptureRequest>& requests,
const hidl_vec<V3_2::BufferCache>& cachesToRemove,
diff --git a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
index 5d6a112..fdc8a5a 100644
--- a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
+++ b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
@@ -84,6 +84,8 @@
camera3_stream_configuration_t *stream_list /*out*/,
hidl_vec<camera3_stream_t*> *streams /*out*/);
void postProcessConfigurationLocked_3_4(const StreamConfiguration& requestedConfiguration);
+ void postProcessConfigurationFailureLocked_3_4(
+ const StreamConfiguration& requestedConfiguration);
Return<void> processCaptureRequest_3_4(
const hidl_vec<V3_4::CaptureRequest>& requests,
diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp
index f9c868d..4fe6c9b 100644
--- a/drm/1.0/default/CryptoPlugin.cpp
+++ b/drm/1.0/default/CryptoPlugin.cpp
@@ -102,11 +102,20 @@
std::unique_ptr<android::CryptoPlugin::SubSample[]> legacySubSamples =
std::make_unique<android::CryptoPlugin::SubSample[]>(subSamples.size());
+ size_t destSize = 0;
for (size_t i = 0; i < subSamples.size(); i++) {
- legacySubSamples[i].mNumBytesOfClearData
- = subSamples[i].numBytesOfClearData;
- legacySubSamples[i].mNumBytesOfEncryptedData
- = subSamples[i].numBytesOfEncryptedData;
+ uint32_t numBytesOfClearData = subSamples[i].numBytesOfClearData;
+ legacySubSamples[i].mNumBytesOfClearData = numBytesOfClearData;
+ uint32_t numBytesOfEncryptedData = subSamples[i].numBytesOfEncryptedData;
+ legacySubSamples[i].mNumBytesOfEncryptedData = numBytesOfEncryptedData;
+ if (__builtin_add_overflow(destSize, numBytesOfClearData, &destSize)) {
+ _hidl_cb(Status::BAD_VALUE, 0, "subsample clear size overflow");
+ return Void();
+ }
+ if (__builtin_add_overflow(destSize, numBytesOfEncryptedData, &destSize)) {
+ _hidl_cb(Status::BAD_VALUE, 0, "subsample encrypted size overflow");
+ return Void();
+ }
}
AString detailMessage;
@@ -138,11 +147,24 @@
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
+
+ if (destSize > destBuffer.size) {
+ _hidl_cb(Status::BAD_VALUE, 0, "subsample sum too large");
+ return Void();
+ }
+
destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
} else if (destination.type == BufferType::NATIVE_HANDLE) {
+ if (!secure) {
+ _hidl_cb(Status::BAD_VALUE, 0, "native handle destination must be secure");
+ return Void();
+ }
native_handle_t *handle = const_cast<native_handle_t *>(
destination.secureMemory.getNativeHandle());
destPtr = static_cast<void *>(handle);
+ } else {
+ _hidl_cb(Status::BAD_VALUE, 0, "invalid destination type");
+ return Void();
}
ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(),
legacyMode, legacyPattern, srcPtr, legacySubSamples.get(),
diff --git a/drm/1.0/default/DrmFactory.cpp b/drm/1.0/default/DrmFactory.cpp
index 7e5d998..05951d7 100644
--- a/drm/1.0/default/DrmFactory.cpp
+++ b/drm/1.0/default/DrmFactory.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2016 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
diff --git a/drm/1.0/default/LegacyPluginPath.cpp b/drm/1.0/default/LegacyPluginPath.cpp
index 369059d..d0a8f90 100644
--- a/drm/1.0/default/LegacyPluginPath.cpp
+++ b/drm/1.0/default/LegacyPluginPath.cpp
@@ -16,6 +16,8 @@
#include "LegacyPluginPath.h"
+#include <unistd.h>
+
#include <cutils/properties.h>
namespace android {
@@ -24,12 +26,16 @@
namespace V1_0 {
namespace implementation {
+// 64-bit DRM depends on OEM libraries that aren't
+// provided for all devices. If the drm hal service
+// is running as 64-bit use the 64-bit libs, otherwise
+// use the 32-bit libs.
const char* getDrmPluginPath() {
- if (property_get_bool("drm.64bit.enabled", false)) {
- return "/vendor/lib64/mediadrm";
- } else {
- return "/vendor/lib/mediadrm";
- }
+#if defined(__LP64__)
+ return "/vendor/lib64/mediadrm";
+#else
+ return "/vendor/lib/mediadrm";
+#endif
}
} // namespace implementation
diff --git a/drm/1.0/default/include/PluginLoader.h b/drm/1.0/default/include/PluginLoader.h
index f387b3c..0c45fb3 100644
--- a/drm/1.0/default/include/PluginLoader.h
+++ b/drm/1.0/default/include/PluginLoader.h
@@ -85,7 +85,10 @@
libraries.push(library);
T* result = createFactoryFunc();
return result;
- }
+ } else {
+ ALOGE("Failed to lookup symbol %s in library %s: %s",
+ entry, path, library->lastError());
+ }
}
return NULL;
}
diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp b/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp
index 7c9e651..0f50577 100644
--- a/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp
+++ b/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp
@@ -32,6 +32,8 @@
#include <log/log.h>
#include <sync/sync.h>
+using namespace HWC2;
+
namespace android {
namespace {
@@ -629,9 +631,10 @@
}
}
-void getCapabilitiesHook(hwc2_device_t* /*device*/, uint32_t* outCount,
- int32_t* /*outCapabilities*/) {
- *outCount = 0;
+void getCapabilitiesHook(hwc2_device_t* device, uint32_t* outCount,
+ int32_t* outCapabilities) {
+ auto& adapter = HWC2OnFbAdapter::cast(device);
+ adapter.getCapabilities(outCount, outCapabilities);
}
int closeHook(hw_device_t* device) {
@@ -656,6 +659,10 @@
mFbInfo.xdpi_scaled = int(mFbDevice->xdpi * 1000.0f);
mFbInfo.ydpi_scaled = int(mFbDevice->ydpi * 1000.0f);
+ // Present fences aren't supported, always indicate PresentFenceIsNotReliable
+ // for FB devices
+ mCapabilities.insert(Capability::PresentFenceIsNotReliable);
+
mVsyncThread.start(0, mFbInfo.vsync_period_ns);
}
@@ -791,6 +798,23 @@
mVsyncThread.enableCallback(enable);
}
+void HWC2OnFbAdapter::getCapabilities(uint32_t* outCount,
+ int32_t* outCapabilities) {
+ if (outCapabilities == nullptr) {
+ *outCount = mCapabilities.size();
+ return;
+ }
+
+ auto capabilityIter = mCapabilities.cbegin();
+ for (size_t written = 0; written < *outCount; ++written) {
+ if (capabilityIter == mCapabilities.cend()) {
+ return;
+ }
+ outCapabilities[written] = static_cast<int32_t>(*capabilityIter);
+ ++capabilityIter;
+ }
+}
+
int64_t HWC2OnFbAdapter::VsyncThread::now() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h b/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h
index d6272fd..f1f11ef 100644
--- a/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h
+++ b/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h
@@ -23,7 +23,11 @@
#include <thread>
#include <unordered_set>
+#define HWC2_INCLUDE_STRINGIFICATION
+#define HWC2_USE_CPP11
#include <hardware/hwcomposer2.h>
+#undef HWC2_INCLUDE_STRINGIFICATION
+#undef HWC2_USE_CPP11
struct framebuffer_device_t;
@@ -75,6 +79,7 @@
void setVsyncCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data);
void enableVsync(bool enable);
+ void getCapabilities(uint32_t* outCount, int32_t* outCapabilities);
private:
framebuffer_device_t* mFbDevice{nullptr};
@@ -90,6 +95,8 @@
buffer_handle_t mBuffer{nullptr};
+ std::unordered_set<HWC2::Capability> mCapabilities;
+
class VsyncThread {
public:
static int64_t now();
diff --git a/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc
index a41d902..efe6dad 100644
--- a/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc
+++ b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc
@@ -4,3 +4,4 @@
group graphics drmrpc
capabilities SYS_NICE
onrestart restart surfaceflinger
+ writepid /dev/cpuset/system-background/tasks
diff --git a/health/2.0/README b/health/2.0/README
index 11e6a7a..dfd965a 100644
--- a/health/2.0/README
+++ b/health/2.0/README
@@ -6,12 +6,7 @@
1. If the device does not have a vendor-specific libhealthd AND does not
implement storage-related APIs, just do the following:
- 1.1 (recommended) To remove healthd from the build,
- PRODUCT_PACKAGES += android.hardware.health@2.0-service.override
- DEVICE_FRAMEWORK_MANIFEST_FILE += \
- system/libhidl/vintfdata/manifest_healthd_exclude.xml
- 1.2 To keep healthd in the build,
- PRODUCT_PACKAGES += android.hardware.health@2.0-service
+ PRODUCT_PACKAGES += android.hardware.health@2.0-service
Otherwise, continue to Step 2.
diff --git a/keymaster/4.0/support/Keymaster.cpp b/keymaster/4.0/support/Keymaster.cpp
index 444298b..9325cc0 100644
--- a/keymaster/4.0/support/Keymaster.cpp
+++ b/keymaster/4.0/support/Keymaster.cpp
@@ -164,10 +164,10 @@
sharingCheck = curSharingCheck;
firstKeymaster = false;
}
- CHECK(curSharingCheck == sharingCheck)
- << "HMAC computation failed for " << *keymaster //
- << " Expected: " << sharingCheck //
- << " got: " << curSharingCheck;
+ if (curSharingCheck != sharingCheck)
+ LOG(WARNING) << "HMAC computation failed for " << *keymaster //
+ << " Expected: " << sharingCheck //
+ << " got: " << curSharingCheck;
});
CHECK(rc.isOk()) << "Failed to communicate with " << *keymaster
<< " error: " << rc.description();
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 784ae30..a2b43f0 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -3899,6 +3899,33 @@
}
/*
+ * AttestationTest.EcAttestationByKeySize
+ *
+ * Verifies that attesting to EC keys works and generates the expected output.
+ */
+TEST_F(AttestationTest, EcAttestationByKeySize) {
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .EcdsaSigningKey(256)
+ .Digest(Digest::SHA_2_256)
+ .Authorization(TAG_INCLUDE_UNIQUE_ID)));
+
+ hidl_vec<hidl_vec<uint8_t>> cert_chain;
+ ASSERT_EQ(ErrorCode::OK,
+ AttestKey(AuthorizationSetBuilder()
+ .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+ .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")),
+ &cert_chain));
+ EXPECT_GE(cert_chain.size(), 2U);
+ EXPECT_TRUE(verify_chain(cert_chain));
+
+ EXPECT_TRUE(verify_attestation_record("challenge", "foo", //
+ key_characteristics_.softwareEnforced, //
+ key_characteristics_.hardwareEnforced, //
+ SecLevel(), cert_chain[0]));
+}
+
+/*
* AttestationTest.EcAttestationRequiresAttestationAppId
*
* Verifies that attesting to EC keys requires app ID