Merge changes from topic "upstream-close-fixes" am: 7663233f5c
am: b6d82825e0
am: 88e9203701
Change-Id: If85dd058799aede5b0770e52b0185d3405f44269
This commit is contained in:
commit
e74d8746cf
4 changed files with 59 additions and 2 deletions
|
@ -286,8 +286,12 @@ interface IDevice {
|
|||
* all currently allocated resources. It is recommended to close
|
||||
* the device on the client side as soon as it is becomes unused.
|
||||
*
|
||||
* Note that all streams must be closed by the client before
|
||||
* attempting to close the device they belong to.
|
||||
*
|
||||
* @return retval OK in case the success.
|
||||
* INVALID_STATE if the device was already closed.
|
||||
* INVALID_STATE if the device was already closed
|
||||
* or there are streams currently opened.
|
||||
*/
|
||||
@exit
|
||||
close() generates (Result retval);
|
||||
|
|
|
@ -53,10 +53,14 @@ Result Device::analyzeStatus(const char* funcName, int status,
|
|||
|
||||
void Device::closeInputStream(audio_stream_in_t* stream) {
|
||||
mDevice->close_input_stream(mDevice, stream);
|
||||
LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "mOpenedStreamsCount is already 0");
|
||||
--mOpenedStreamsCount;
|
||||
}
|
||||
|
||||
void Device::closeOutputStream(audio_stream_out_t* stream) {
|
||||
mDevice->close_output_stream(mDevice, stream);
|
||||
LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "mOpenedStreamsCount is already 0");
|
||||
--mOpenedStreamsCount;
|
||||
}
|
||||
|
||||
char* Device::halGetParameters(const char* keys) {
|
||||
|
@ -158,6 +162,7 @@ std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamImpl(int32_t ioHandle
|
|||
sp<IStreamOut> streamOut;
|
||||
if (status == OK) {
|
||||
streamOut = new StreamOut(this, halStream);
|
||||
++mOpenedStreamsCount;
|
||||
}
|
||||
HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
|
||||
return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
|
||||
|
@ -184,6 +189,7 @@ std::tuple<Result, sp<IStreamIn>> Device::openInputStreamImpl(
|
|||
sp<IStreamIn> streamIn;
|
||||
if (status == OK) {
|
||||
streamIn = new StreamIn(this, halStream);
|
||||
++mOpenedStreamsCount;
|
||||
}
|
||||
HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
|
||||
return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn};
|
||||
|
@ -383,7 +389,7 @@ Return<Result> Device::setConnectedState(const DeviceAddress& address, bool conn
|
|||
#endif
|
||||
|
||||
Result Device::doClose() {
|
||||
if (mIsClosed) return Result::INVALID_STATE;
|
||||
if (mIsClosed || mOpenedStreamsCount != 0) return Result::INVALID_STATE;
|
||||
mIsClosed = true;
|
||||
return analyzeStatus("close", audio_hw_device_close(mDevice));
|
||||
}
|
||||
|
|
|
@ -130,6 +130,7 @@ struct Device : public IDevice, public ParametersUtil {
|
|||
private:
|
||||
bool mIsClosed;
|
||||
audio_hw_device_t* mDevice;
|
||||
int mOpenedStreamsCount = 0;
|
||||
|
||||
virtual ~Device();
|
||||
|
||||
|
|
|
@ -145,3 +145,49 @@ const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
|
|||
}();
|
||||
return parameters;
|
||||
}
|
||||
|
||||
TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) {
|
||||
doc::test("Verify that a device can't be closed if there are streams opened");
|
||||
DeviceAddress address{.device = AudioDevice::OUT_DEFAULT};
|
||||
AudioConfig config{};
|
||||
auto flags = hidl_bitfield<AudioOutputFlag>(AudioOutputFlag::NONE);
|
||||
SourceMetadata initMetadata = {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}};
|
||||
sp<IStreamOut> stream;
|
||||
StreamHelper<IStreamOut> helper(stream);
|
||||
AudioConfig suggestedConfig{};
|
||||
ASSERT_NO_FATAL_FAILURE(helper.open(
|
||||
[&](AudioIoHandle handle, AudioConfig config, auto cb) {
|
||||
return getDevice()->openOutputStream(handle, address, config, flags, initMetadata,
|
||||
cb);
|
||||
},
|
||||
config, &res, &suggestedConfig));
|
||||
ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close());
|
||||
ASSERT_NO_FATAL_FAILURE(helper.close(true /*clear*/, &res));
|
||||
ASSERT_OK(getDevice()->close());
|
||||
ASSERT_TRUE(resetDevice());
|
||||
}
|
||||
|
||||
TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) {
|
||||
doc::test("Verify that a device can't be closed if there are streams opened");
|
||||
auto module = getCachedPolicyConfig().getModuleFromName(getDeviceName());
|
||||
if (module->getInputProfiles().empty()) {
|
||||
GTEST_SKIP() << "Device doesn't have input profiles";
|
||||
}
|
||||
DeviceAddress address{.device = AudioDevice::IN_DEFAULT};
|
||||
AudioConfig config{};
|
||||
auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
|
||||
SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
|
||||
sp<IStreamIn> stream;
|
||||
StreamHelper<IStreamIn> helper(stream);
|
||||
AudioConfig suggestedConfig{};
|
||||
ASSERT_NO_FATAL_FAILURE(helper.open(
|
||||
[&](AudioIoHandle handle, AudioConfig config, auto cb) {
|
||||
return getDevice()->openInputStream(handle, address, config, flags, initMetadata,
|
||||
cb);
|
||||
},
|
||||
config, &res, &suggestedConfig));
|
||||
ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close());
|
||||
ASSERT_NO_FATAL_FAILURE(helper.close(true /*clear*/, &res));
|
||||
ASSERT_OK(getDevice()->close());
|
||||
ASSERT_TRUE(resetDevice());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue