Loading audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ interface IModule { boolean supportsVariableLatency(); int getAAudioMixerBurstCount(); int getAAudioHardwareBurstMinUsec(); void prepareToDisconnectExternalDevice(int portId); const int DEFAULT_AAUDIO_MIXER_BURST_COUNT = 2; const int DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US = 1000; @VintfStability Loading audio/aidl/android/hardware/audio/core/IModule.aidl +29 −7 Original line number Diff line number Diff line Loading @@ -206,8 +206,10 @@ interface IModule { * after successful connection of an external device. * * Handling of a disconnect is done in a reverse order: * 1. Reset port configuration using the 'resetAudioPortConfig' method. * 2. Release the connected device port by calling the 'disconnectExternalDevice' * 1. Notify the HAL module to prepare for device disconnection using * 'prepareToDisconnectExternalDevice' method. * 2. Reset port configuration using the 'resetAudioPortConfig' method. * 3. Release the connected device port by calling the 'disconnectExternalDevice' * method. This also removes the audio routes associated with this * device port. * Loading @@ -234,11 +236,15 @@ interface IModule { * instance previously instantiated using the 'connectExternalDevice' * method. * * The framework will call this method before closing streams and resetting * patches. This call can be used by the HAL module to prepare itself to * device disconnection. If the HAL module indicates an error after the first * call, the framework will call this method once again after closing associated * streams and patches. * On AIDL HAL v1, the framework will call this method before closing streams * and resetting patches. This call can be used by the HAL module to prepare * itself to device disconnection. If the HAL module indicates an error after * the first call, the framework will call this method once again after closing * associated streams and patches. * * On AIDL HAL v2 and later, the framework will call 'prepareToDisconnectExternalDevice' * method to notify the HAL module to prepare itself for device disconnection. The * framework will only call this method after closing associated streams and patches. * * @throws EX_ILLEGAL_ARGUMENT In the following cases: * - If the port can not be found by the ID. Loading Loading @@ -912,4 +918,20 @@ interface IModule { * @throw EX_UNSUPPORTED_OPERATION If the module does not support aaudio MMAP. */ int getAAudioHardwareBurstMinUsec(); /** * Notify the HAL module to prepare for disconnecting an external device. * * This method is used to inform the HAL module that 'disconnectExternalDevice' will be * called soon. The HAL module can rely on this method to abort active data operations * early. The 'portId' must be of a connected device Port instance previously instantiated * using 'connectExternalDevice' method. 'disconnectExternalDevice' method will be called * soon after this method with the same 'portId'. * * @param portId The ID of the audio port that is about to disconnect * @throws EX_ILLEGAL_ARGUMENT In the following cases: * - If the port can not be found by the ID. * - If this is not a connected device port. */ void prepareToDisconnectExternalDevice(int portId); } audio/aidl/default/Module.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -758,6 +758,28 @@ ndk::ScopedAStatus Module::disconnectExternalDevice(int32_t in_portId) { return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Module::prepareToDisconnectExternalDevice(int32_t in_portId) { auto& ports = getConfig().ports; auto portIt = findById<AudioPort>(ports, in_portId); if (portIt == ports.end()) { LOG(ERROR) << __func__ << ": port id " << in_portId << " not found"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } if (portIt->ext.getTag() != AudioPortExt::Tag::device) { LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a device port"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } auto connectedPortsIt = mConnectedDevicePorts.find(in_portId); if (connectedPortsIt == mConnectedDevicePorts.end()) { LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a connected device port"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } onPrepareToDisconnectExternalDevice(*portIt); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Module::getAudioPatches(std::vector<AudioPatch>* _aidl_return) { *_aidl_return = getConfig().patches; LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " patches"; Loading Loading @@ -1537,6 +1559,11 @@ void Module::onExternalDeviceConnectionChanged( LOG(DEBUG) << __func__ << ": do nothing and return"; } void Module::onPrepareToDisconnectExternalDevice( const ::aidl::android::media::audio::common::AudioPort& audioPort __unused) { LOG(DEBUG) << __func__ << ": do nothing and return"; } ndk::ScopedAStatus Module::onMasterMuteChanged(bool mute __unused) { LOG(VERBOSE) << __func__ << ": do nothing and return ok"; return ndk::ScopedAStatus::ok(); Loading audio/aidl/default/include/core-impl/Module.h +3 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ class Module : public BnModule { const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData, ::aidl::android::media::audio::common::AudioPort* _aidl_return) override; ndk::ScopedAStatus disconnectExternalDevice(int32_t in_portId) override; ndk::ScopedAStatus prepareToDisconnectExternalDevice(int32_t in_portId) override; ndk::ScopedAStatus getAudioPatches(std::vector<AudioPatch>* _aidl_return) override; ndk::ScopedAStatus getAudioPort( int32_t in_portId, Loading Loading @@ -195,6 +196,8 @@ class Module : public BnModule { const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks); virtual void onExternalDeviceConnectionChanged( const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected); virtual void onPrepareToDisconnectExternalDevice( const ::aidl::android::media::audio::common::AudioPort& audioPort); virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute); virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume); virtual std::vector<::aidl::android::media::audio::common::MicrophoneInfo> getMicrophoneInfos(); Loading audio/aidl/vts/TestUtils.h +29 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,23 @@ inline ::testing::AssertionResult assertResult(const char* exp_expr, const char* << "\n but is has completed with: " << status; } inline ::testing::AssertionResult assertIsOkOrUnknownTransaction( const char* expr, const ::ndk::ScopedAStatus& status) { if (status.getStatus() == STATUS_UNKNOWN_TRANSACTION) { return ::testing::AssertionSuccess(); } return assertIsOk(expr, status); } inline ::testing::AssertionResult assertResultOrUnknownTransaction( const char* exp_expr, const char* act_expr, int32_t expected, const ::ndk::ScopedAStatus& status) { if (status.getStatus() == STATUS_UNKNOWN_TRANSACTION) { return ::testing::AssertionSuccess(); } return assertResult(exp_expr, act_expr, expected, status); } } // namespace detail } // namespace android::hardware::audio::common::testing Loading @@ -93,3 +110,15 @@ inline ::testing::AssertionResult assertResult(const char* exp_expr, const char* GTEST_SKIP() << "Skip data path for offload"; \ } \ }) // Test that the transaction status 'isOk' if it is a known transaction #define EXPECT_IS_OK_OR_UNKNOWN_TRANSACTION(ret) \ EXPECT_PRED_FORMAT1( \ ::android::hardware::audio::common::testing::detail::assertIsOkOrUnknownTransaction, \ ret) // Test that the transaction status is as expected if it is a known transaction #define EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(expected, ret) \ EXPECT_PRED_FORMAT2( \ ::android::hardware::audio::common::testing::detail::assertResultOrUnknownTransaction, \ expected, ret) Loading
audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ interface IModule { boolean supportsVariableLatency(); int getAAudioMixerBurstCount(); int getAAudioHardwareBurstMinUsec(); void prepareToDisconnectExternalDevice(int portId); const int DEFAULT_AAUDIO_MIXER_BURST_COUNT = 2; const int DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US = 1000; @VintfStability Loading
audio/aidl/android/hardware/audio/core/IModule.aidl +29 −7 Original line number Diff line number Diff line Loading @@ -206,8 +206,10 @@ interface IModule { * after successful connection of an external device. * * Handling of a disconnect is done in a reverse order: * 1. Reset port configuration using the 'resetAudioPortConfig' method. * 2. Release the connected device port by calling the 'disconnectExternalDevice' * 1. Notify the HAL module to prepare for device disconnection using * 'prepareToDisconnectExternalDevice' method. * 2. Reset port configuration using the 'resetAudioPortConfig' method. * 3. Release the connected device port by calling the 'disconnectExternalDevice' * method. This also removes the audio routes associated with this * device port. * Loading @@ -234,11 +236,15 @@ interface IModule { * instance previously instantiated using the 'connectExternalDevice' * method. * * The framework will call this method before closing streams and resetting * patches. This call can be used by the HAL module to prepare itself to * device disconnection. If the HAL module indicates an error after the first * call, the framework will call this method once again after closing associated * streams and patches. * On AIDL HAL v1, the framework will call this method before closing streams * and resetting patches. This call can be used by the HAL module to prepare * itself to device disconnection. If the HAL module indicates an error after * the first call, the framework will call this method once again after closing * associated streams and patches. * * On AIDL HAL v2 and later, the framework will call 'prepareToDisconnectExternalDevice' * method to notify the HAL module to prepare itself for device disconnection. The * framework will only call this method after closing associated streams and patches. * * @throws EX_ILLEGAL_ARGUMENT In the following cases: * - If the port can not be found by the ID. Loading Loading @@ -912,4 +918,20 @@ interface IModule { * @throw EX_UNSUPPORTED_OPERATION If the module does not support aaudio MMAP. */ int getAAudioHardwareBurstMinUsec(); /** * Notify the HAL module to prepare for disconnecting an external device. * * This method is used to inform the HAL module that 'disconnectExternalDevice' will be * called soon. The HAL module can rely on this method to abort active data operations * early. The 'portId' must be of a connected device Port instance previously instantiated * using 'connectExternalDevice' method. 'disconnectExternalDevice' method will be called * soon after this method with the same 'portId'. * * @param portId The ID of the audio port that is about to disconnect * @throws EX_ILLEGAL_ARGUMENT In the following cases: * - If the port can not be found by the ID. * - If this is not a connected device port. */ void prepareToDisconnectExternalDevice(int portId); }
audio/aidl/default/Module.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -758,6 +758,28 @@ ndk::ScopedAStatus Module::disconnectExternalDevice(int32_t in_portId) { return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Module::prepareToDisconnectExternalDevice(int32_t in_portId) { auto& ports = getConfig().ports; auto portIt = findById<AudioPort>(ports, in_portId); if (portIt == ports.end()) { LOG(ERROR) << __func__ << ": port id " << in_portId << " not found"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } if (portIt->ext.getTag() != AudioPortExt::Tag::device) { LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a device port"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } auto connectedPortsIt = mConnectedDevicePorts.find(in_portId); if (connectedPortsIt == mConnectedDevicePorts.end()) { LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a connected device port"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } onPrepareToDisconnectExternalDevice(*portIt); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Module::getAudioPatches(std::vector<AudioPatch>* _aidl_return) { *_aidl_return = getConfig().patches; LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " patches"; Loading Loading @@ -1537,6 +1559,11 @@ void Module::onExternalDeviceConnectionChanged( LOG(DEBUG) << __func__ << ": do nothing and return"; } void Module::onPrepareToDisconnectExternalDevice( const ::aidl::android::media::audio::common::AudioPort& audioPort __unused) { LOG(DEBUG) << __func__ << ": do nothing and return"; } ndk::ScopedAStatus Module::onMasterMuteChanged(bool mute __unused) { LOG(VERBOSE) << __func__ << ": do nothing and return ok"; return ndk::ScopedAStatus::ok(); Loading
audio/aidl/default/include/core-impl/Module.h +3 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ class Module : public BnModule { const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData, ::aidl::android::media::audio::common::AudioPort* _aidl_return) override; ndk::ScopedAStatus disconnectExternalDevice(int32_t in_portId) override; ndk::ScopedAStatus prepareToDisconnectExternalDevice(int32_t in_portId) override; ndk::ScopedAStatus getAudioPatches(std::vector<AudioPatch>* _aidl_return) override; ndk::ScopedAStatus getAudioPort( int32_t in_portId, Loading Loading @@ -195,6 +196,8 @@ class Module : public BnModule { const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks); virtual void onExternalDeviceConnectionChanged( const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected); virtual void onPrepareToDisconnectExternalDevice( const ::aidl::android::media::audio::common::AudioPort& audioPort); virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute); virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume); virtual std::vector<::aidl::android::media::audio::common::MicrophoneInfo> getMicrophoneInfos(); Loading
audio/aidl/vts/TestUtils.h +29 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,23 @@ inline ::testing::AssertionResult assertResult(const char* exp_expr, const char* << "\n but is has completed with: " << status; } inline ::testing::AssertionResult assertIsOkOrUnknownTransaction( const char* expr, const ::ndk::ScopedAStatus& status) { if (status.getStatus() == STATUS_UNKNOWN_TRANSACTION) { return ::testing::AssertionSuccess(); } return assertIsOk(expr, status); } inline ::testing::AssertionResult assertResultOrUnknownTransaction( const char* exp_expr, const char* act_expr, int32_t expected, const ::ndk::ScopedAStatus& status) { if (status.getStatus() == STATUS_UNKNOWN_TRANSACTION) { return ::testing::AssertionSuccess(); } return assertResult(exp_expr, act_expr, expected, status); } } // namespace detail } // namespace android::hardware::audio::common::testing Loading @@ -93,3 +110,15 @@ inline ::testing::AssertionResult assertResult(const char* exp_expr, const char* GTEST_SKIP() << "Skip data path for offload"; \ } \ }) // Test that the transaction status 'isOk' if it is a known transaction #define EXPECT_IS_OK_OR_UNKNOWN_TRANSACTION(ret) \ EXPECT_PRED_FORMAT1( \ ::android::hardware::audio::common::testing::detail::assertIsOkOrUnknownTransaction, \ ret) // Test that the transaction status is as expected if it is a known transaction #define EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(expected, ret) \ EXPECT_PRED_FORMAT2( \ ::android::hardware::audio::common::testing::detail::assertResultOrUnknownTransaction, \ expected, ret)