Audio Aidl: Update binder::Status return code handling

Add statusTFromBinderStatus() and binderStatusFromStatusT()
as methods to standardize binder status codes for native
audio service cross-language compatibility.

Test: atest audio_aidl_status_tests
Bug: 175338323
Change-Id: I48c543689d5a9a464c0d68fb6263dedff43ceca9
diff --git a/media/libaaudio/src/binding/AAudioBinderAdapter.cpp b/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
index 2b2fe6d..6e3a1c8 100644
--- a/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
+++ b/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
@@ -15,10 +15,12 @@
  */
 
 #include <binding/AAudioBinderAdapter.h>
+#include <media/AidlConversionUtil.h>
 #include <utility/AAudioUtilities.h>
 
 namespace aaudio {
 
+using android::aidl_utils::statusTFromBinderStatus;
 using android::binder::Status;
 
 AAudioBinderAdapter::AAudioBinderAdapter(IAAudioService* delegate)
@@ -36,7 +38,7 @@
                                           &params,
                                           &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     config = params;
     return result;
@@ -46,7 +48,7 @@
     aaudio_result_t result;
     Status status = mDelegate->closeStream(streamHandle, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -59,7 +61,7 @@
                                                     &endpoint,
                                                     &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     endpointOut = std::move(endpoint);
     return result;
@@ -69,7 +71,7 @@
     aaudio_result_t result;
     Status status = mDelegate->startStream(streamHandle, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -78,7 +80,7 @@
     aaudio_result_t result;
     Status status = mDelegate->pauseStream(streamHandle, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -87,7 +89,7 @@
     aaudio_result_t result;
     Status status = mDelegate->stopStream(streamHandle, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -96,7 +98,7 @@
     aaudio_result_t result;
     Status status = mDelegate->flushStream(streamHandle, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -107,7 +109,7 @@
     aaudio_result_t result;
     Status status = mDelegate->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -117,7 +119,7 @@
     aaudio_result_t result;
     Status status = mDelegate->unregisterAudioThread(streamHandle, clientThreadId, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 1d036d0..af8ff19 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -558,7 +558,7 @@
         if (status < 0) { // a non-negative value is the volume shaper id.
             ALOGE("applyVolumeShaper() failed with status %d", status);
         }
-        return binder::Status::fromStatusT(status);
+        return aidl_utils::binderStatusFromStatusT(status);
     } else {
         ALOGD("applyVolumeShaper()"
                       " no AudioTrack for volume control from IPlayer");
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index ae899c0..79ea1bb 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -30,7 +30,7 @@
 #include <utils/Log.h>
 
 namespace android {
-
+using aidl_utils::statusTFromBinderStatus;
 using binder::Status;
 
 namespace {
@@ -262,7 +262,7 @@
             bs = mIEffect->disable(&status);
         }
         if (!bs.isOk()) {
-            status = bs.transactionError();
+            status = statusTFromBinderStatus(bs);
         }
         if (status == NO_ERROR) {
             mEnabled = enabled;
@@ -303,7 +303,7 @@
 
     Status bs = mIEffect->command(cmdCode, data, *replySize, &response, &status);
     if (!bs.isOk()) {
-        status = bs.transactionError();
+        status = statusTFromBinderStatus(bs);
     }
     if (status == NO_ERROR) {
         memcpy(replyData, response.data(), response.size());
@@ -351,7 +351,7 @@
                                   &response,
                                   &status);
     if (!bs.isOk()) {
-        status = bs.transactionError();
+        status = statusTFromBinderStatus(bs);
         return status;
     }
     assert(response.size() == sizeof(int));
@@ -410,7 +410,7 @@
                                   &response,
                                   &status);
     if (!bs.isOk()) {
-        status = bs.transactionError();
+        status = statusTFromBinderStatus(bs);
     }
     return status;
 }
@@ -441,7 +441,7 @@
 
     Status bs = mIEffect->command(EFFECT_CMD_GET_PARAM, cmd, psize, &response, &status);
     if (!bs.isOk()) {
-        status = bs.transactionError();
+        status = statusTFromBinderStatus(bs);
         return status;
     }
     memcpy(param, response.data(), response.size());
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index f01b1d0..112cb67 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -47,6 +47,8 @@
 #define WAIT_PERIOD_MS          10
 
 namespace android {
+using aidl_utils::statusTFromBinderStatus;
+
 // ---------------------------------------------------------------------------
 
 // static
@@ -450,7 +452,7 @@
     mActive = true;
 
     if (!(flags & CBLK_INVALID)) {
-        status = mAudioRecord->start(event, triggerSession).transactionError();
+        status = statusTFromBinderStatus(mAudioRecord->start(event, triggerSession));
         if (status == DEAD_OBJECT) {
             flags |= CBLK_INVALID;
         }
@@ -1439,8 +1441,8 @@
         if (mActive) {
             // callback thread or sync event hasn't changed
             // FIXME this fails if we have a new AudioFlinger instance
-            result = mAudioRecord->start(
-                AudioSystem::SYNC_EVENT_SAME, AUDIO_SESSION_NONE).transactionError();
+            result = statusTFromBinderStatus(mAudioRecord->start(
+                AudioSystem::SYNC_EVENT_SAME, AUDIO_SESSION_NONE));
         }
         mFramesReadServerOffset = mFramesRead; // server resets to zero so we need an offset.
     }
@@ -1531,7 +1533,7 @@
 {
     AutoMutex lock(mLock);
     std::vector<media::MicrophoneInfoData> mics;
-    status_t status = mAudioRecord->getActiveMicrophones(&mics).transactionError();
+    status_t status = statusTFromBinderStatus(mAudioRecord->getActiveMicrophones(&mics));
     activeMicrophones->resize(mics.size());
     for (size_t i = 0; status == OK && i < mics.size(); ++i) {
         status = activeMicrophones->at(i).readFromParcelable(mics[i]);
@@ -1552,7 +1554,7 @@
         // the internal AudioRecord hasn't be created yet, so just stash the attribute.
         return OK;
     } else {
-        return mAudioRecord->setPreferredMicrophoneDirection(direction).transactionError();
+        return statusTFromBinderStatus(mAudioRecord->setPreferredMicrophoneDirection(direction));
     }
 }
 
@@ -1568,7 +1570,7 @@
         // the internal AudioRecord hasn't be created yet, so just stash the attribute.
         return OK;
     } else {
-        return mAudioRecord->setPreferredMicrophoneFieldDimension(zoom).transactionError();
+        return statusTFromBinderStatus(mAudioRecord->setPreferredMicrophoneFieldDimension(zoom));
     }
 }
 
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 9aef794..09fcc66 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -35,7 +35,7 @@
 
 #define VALUE_OR_RETURN_BINDER_STATUS(x) \
     ({ auto _tmp = (x); \
-       if (!_tmp.ok()) return Status::fromStatusT(_tmp.error()); \
+       if (!_tmp.ok()) return aidl_utils::binderStatusFromStatusT(_tmp.error()); \
        std::move(_tmp.value()); })
 
 // ----------------------------------------------------------------------------
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index d9b4394..20124df 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -28,6 +28,7 @@
 
 namespace android {
 
+using aidl_utils::statusTFromBinderStatus;
 using binder::Status;
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -214,19 +215,19 @@
 
 status_t AudioFlingerClientAdapter::createTrack(const media::CreateTrackRequest& input,
                                                 media::CreateTrackResponse& output) {
-    return mDelegate->createTrack(input, &output).transactionError();
+    return statusTFromBinderStatus(mDelegate->createTrack(input, &output));
 }
 
 status_t AudioFlingerClientAdapter::createRecord(const media::CreateRecordRequest& input,
                                                  media::CreateRecordResponse& output) {
-    return mDelegate->createRecord(input, &output).transactionError();
+    return statusTFromBinderStatus(mDelegate->createRecord(input, &output));
 }
 
 uint32_t AudioFlingerClientAdapter::sampleRate(audio_io_handle_t ioHandle) const {
     auto result = [&]() -> ConversionResult<uint32_t> {
         int32_t ioHandleAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
         int32_t aidlRet;
-        RETURN_IF_ERROR(mDelegate->sampleRate(ioHandleAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->sampleRate(ioHandleAidl, &aidlRet)));
         return convertIntegral<uint32_t>(aidlRet);
     }();
     // Failure is ignored.
@@ -237,7 +238,7 @@
     auto result = [&]() -> ConversionResult<audio_format_t> {
         int32_t outputAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(output));
         media::audio::common::AudioFormat aidlRet;
-        RETURN_IF_ERROR(mDelegate->format(outputAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->format(outputAidl, &aidlRet)));
         return aidl2legacy_AudioFormat_audio_format_t(aidlRet);
     }();
     return result.value_or(AUDIO_FORMAT_INVALID);
@@ -247,7 +248,7 @@
     auto result = [&]() -> ConversionResult<size_t> {
         int32_t ioHandleAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
         int64_t aidlRet;
-        RETURN_IF_ERROR(mDelegate->frameCount(ioHandleAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->frameCount(ioHandleAidl, &aidlRet)));
         return convertIntegral<size_t>(aidlRet);
     }();
     // Failure is ignored.
@@ -258,7 +259,7 @@
     auto result = [&]() -> ConversionResult<uint32_t> {
         int32_t outputAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(output));
         int32_t aidlRet;
-        RETURN_IF_ERROR(mDelegate->latency(outputAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->latency(outputAidl, &aidlRet)));
         return convertIntegral<uint32_t>(aidlRet);
     }();
     // Failure is ignored.
@@ -266,17 +267,17 @@
 }
 
 status_t AudioFlingerClientAdapter::setMasterVolume(float value) {
-    return mDelegate->setMasterVolume(value).transactionError();
+    return statusTFromBinderStatus(mDelegate->setMasterVolume(value));
 }
 
 status_t AudioFlingerClientAdapter::setMasterMute(bool muted) {
-    return mDelegate->setMasterMute(muted).transactionError();
+    return statusTFromBinderStatus(mDelegate->setMasterMute(muted));
 }
 
 float AudioFlingerClientAdapter::masterVolume() const {
     auto result = [&]() -> ConversionResult<float> {
         float aidlRet;
-        RETURN_IF_ERROR(mDelegate->masterVolume(&aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->masterVolume(&aidlRet)));
         return aidlRet;
     }();
     // Failure is ignored.
@@ -286,7 +287,7 @@
 bool AudioFlingerClientAdapter::masterMute() const {
     auto result = [&]() -> ConversionResult<bool> {
         bool aidlRet;
-        RETURN_IF_ERROR(mDelegate->masterMute(&aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->masterMute(&aidlRet)));
         return aidlRet;
     }();
     // Failure is ignored.
@@ -294,11 +295,11 @@
 }
 
 status_t AudioFlingerClientAdapter::setMasterBalance(float balance) {
-    return mDelegate->setMasterBalance(balance).transactionError();
+    return statusTFromBinderStatus(mDelegate->setMasterBalance(balance));
 }
 
 status_t AudioFlingerClientAdapter::getMasterBalance(float* balance) const{
-    return mDelegate->getMasterBalance(balance).transactionError();
+    return statusTFromBinderStatus(mDelegate->getMasterBalance(balance));
 }
 
 status_t AudioFlingerClientAdapter::setStreamVolume(audio_stream_type_t stream, float value,
@@ -306,13 +307,13 @@
     media::AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
     int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
-    return mDelegate->setStreamVolume(streamAidl, value, outputAidl).transactionError();
+    return statusTFromBinderStatus(mDelegate->setStreamVolume(streamAidl, value, outputAidl));
 }
 
 status_t AudioFlingerClientAdapter::setStreamMute(audio_stream_type_t stream, bool muted) {
     media::AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
-    return mDelegate->setStreamMute(streamAidl, muted).transactionError();
+    return statusTFromBinderStatus(mDelegate->setStreamMute(streamAidl, muted));
 }
 
 float AudioFlingerClientAdapter::streamVolume(audio_stream_type_t stream,
@@ -322,8 +323,8 @@
                 legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
         int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
         float aidlRet;
-        RETURN_IF_ERROR(
-                mDelegate->streamVolume(streamAidl, outputAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->streamVolume(streamAidl, outputAidl, &aidlRet)));
         return aidlRet;
     }();
     // Failure is ignored.
@@ -335,8 +336,8 @@
         media::AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
                 legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
         bool aidlRet;
-        RETURN_IF_ERROR(
-                mDelegate->streamMute(streamAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->streamMute(streamAidl, &aidlRet)));
         return aidlRet;
     }();
     // Failure is ignored.
@@ -345,18 +346,18 @@
 
 status_t AudioFlingerClientAdapter::setMode(audio_mode_t mode) {
     media::AudioMode modeAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_mode_t_AudioMode(mode));
-    return mDelegate->setMode(modeAidl).transactionError();
+    return statusTFromBinderStatus(mDelegate->setMode(modeAidl));
 }
 
 status_t AudioFlingerClientAdapter::setMicMute(bool state) {
-    return mDelegate->setMicMute(state).transactionError();
+    return statusTFromBinderStatus(mDelegate->setMicMute(state));
 }
 
 bool AudioFlingerClientAdapter::getMicMute() const {
     auto result = [&]() -> ConversionResult<bool> {
         bool aidlRet;
-        RETURN_IF_ERROR(
-                mDelegate->getMicMute(&aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getMicMute(&aidlRet)));
         return aidlRet;
     }();
     // Failure is ignored.
@@ -367,7 +368,7 @@
     auto result = [&]() -> status_t {
         int32_t portIdAidl = VALUE_OR_RETURN_STATUS(
                 legacy2aidl_audio_port_handle_t_int32_t(portId));
-        return mDelegate->setRecordSilenced(portIdAidl, silenced).transactionError();
+        return statusTFromBinderStatus(mDelegate->setRecordSilenced(portIdAidl, silenced));
     }();
     // Failure is ignored.
     (void) result;
@@ -378,7 +379,7 @@
     int32_t ioHandleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
     std::string keyValuePairsAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_String8_string(keyValuePairs));
-    return mDelegate->setParameters(ioHandleAidl, keyValuePairsAidl).transactionError();
+    return statusTFromBinderStatus(mDelegate->setParameters(ioHandleAidl, keyValuePairsAidl));
 }
 
 String8 AudioFlingerClientAdapter::getParameters(audio_io_handle_t ioHandle, const String8& keys)
@@ -387,8 +388,8 @@
         int32_t ioHandleAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
         std::string keysAidl = VALUE_OR_RETURN(legacy2aidl_String8_string(keys));
         std::string aidlRet;
-        RETURN_IF_ERROR(
-                mDelegate->getParameters(ioHandleAidl, keysAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getParameters(ioHandleAidl, keysAidl, &aidlRet)));
         return aidl2legacy_string_view_String8(aidlRet);
     }();
     // Failure is ignored.
@@ -409,9 +410,9 @@
         int32_t channelMaskAidl = VALUE_OR_RETURN(
                 legacy2aidl_audio_channel_mask_t_int32_t(channelMask));
         int64_t aidlRet;
-        RETURN_IF_ERROR(
+        RETURN_IF_ERROR(statusTFromBinderStatus(
                 mDelegate->getInputBufferSize(sampleRateAidl, formatAidl, channelMaskAidl,
-                                              &aidlRet).transactionError());
+                                              &aidlRet)));
         return convertIntegral<size_t>(aidlRet);
     }();
     // Failure is ignored.
@@ -420,7 +421,7 @@
 
 status_t AudioFlingerClientAdapter::openOutput(const media::OpenOutputRequest& request,
                                                media::OpenOutputResponse* response) {
-    return mDelegate->openOutput(request, response).transactionError();
+    return statusTFromBinderStatus(mDelegate->openOutput(request, response));
 }
 
 audio_io_handle_t AudioFlingerClientAdapter::openDuplicateOutput(audio_io_handle_t output1,
@@ -429,8 +430,8 @@
         int32_t output1Aidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(output1));
         int32_t output2Aidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(output2));
         int32_t aidlRet;
-        RETURN_IF_ERROR(mDelegate->openDuplicateOutput(output1Aidl, output2Aidl,
-                                                       &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->openDuplicateOutput(output1Aidl, output2Aidl, &aidlRet)));
         return aidl2legacy_int32_t_audio_io_handle_t(aidlRet);
     }();
     // Failure is ignored.
@@ -439,44 +440,45 @@
 
 status_t AudioFlingerClientAdapter::closeOutput(audio_io_handle_t output) {
     int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
-    return mDelegate->closeOutput(outputAidl).transactionError();
+    return statusTFromBinderStatus(mDelegate->closeOutput(outputAidl));
 }
 
 status_t AudioFlingerClientAdapter::suspendOutput(audio_io_handle_t output) {
     int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
-    return mDelegate->suspendOutput(outputAidl).transactionError();
+    return statusTFromBinderStatus(mDelegate->suspendOutput(outputAidl));
 }
 
 status_t AudioFlingerClientAdapter::restoreOutput(audio_io_handle_t output) {
     int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
-    return mDelegate->restoreOutput(outputAidl).transactionError();
+    return statusTFromBinderStatus(mDelegate->restoreOutput(outputAidl));
 }
 
 status_t AudioFlingerClientAdapter::openInput(const media::OpenInputRequest& request,
                                               media::OpenInputResponse* response) {
-    return mDelegate->openInput(request, response).transactionError();
+    return statusTFromBinderStatus(mDelegate->openInput(request, response));
 }
 
 status_t AudioFlingerClientAdapter::closeInput(audio_io_handle_t input) {
     int32_t inputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(input));
-    return mDelegate->closeInput(inputAidl).transactionError();
+    return statusTFromBinderStatus(mDelegate->closeInput(inputAidl));
 }
 
 status_t AudioFlingerClientAdapter::invalidateStream(audio_stream_type_t stream) {
     media::AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
-    return mDelegate->invalidateStream(streamAidl).transactionError();
+    return statusTFromBinderStatus(mDelegate->invalidateStream(streamAidl));
 }
 
 status_t AudioFlingerClientAdapter::setVoiceVolume(float volume) {
-    return mDelegate->setVoiceVolume(volume).transactionError();
+    return statusTFromBinderStatus(mDelegate->setVoiceVolume(volume));
 }
 
 status_t AudioFlingerClientAdapter::getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames,
                                                       audio_io_handle_t output) const {
     int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
     media::RenderPosition aidlRet;
-    RETURN_STATUS_IF_ERROR(mDelegate->getRenderPosition(outputAidl, &aidlRet).transactionError());
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->getRenderPosition(outputAidl, &aidlRet)));
     if (halFrames != nullptr) {
         *halFrames = VALUE_OR_RETURN_STATUS(convertIntegral<uint32_t>(aidlRet.halFrames));
     }
@@ -490,7 +492,8 @@
     auto result = [&]() -> ConversionResult<uint32_t> {
         int32_t ioHandleAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
         int32_t aidlRet;
-        RETURN_IF_ERROR(mDelegate->getInputFramesLost(ioHandleAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getInputFramesLost(ioHandleAidl, &aidlRet)));
         return convertIntegral<uint32_t>(aidlRet);
     }();
     // Failure is ignored.
@@ -502,7 +505,8 @@
         media::AudioUniqueIdUse useAidl = VALUE_OR_RETURN(
                 legacy2aidl_audio_unique_id_use_t_AudioUniqueIdUse(use));
         int32_t aidlRet;
-        RETURN_IF_ERROR(mDelegate->newAudioUniqueId(useAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->newAudioUniqueId(useAidl, &aidlRet)));
         return aidl2legacy_int32_t_audio_unique_id_t(aidlRet);
     }();
     return result.value_or(AUDIO_UNIQUE_ID_ALLOCATE);
@@ -515,8 +519,8 @@
                 legacy2aidl_audio_session_t_int32_t(audioSession));
         int32_t pidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(pid));
         int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(uid));
-        return mDelegate->acquireAudioSessionId(audioSessionAidl, pidAidl,
-                                                uidAidl).transactionError();
+        return statusTFromBinderStatus(
+                mDelegate->acquireAudioSessionId(audioSessionAidl, pidAidl, uidAidl));
     }();
     // Failure is ignored.
 }
@@ -526,14 +530,16 @@
         int32_t audioSessionAidl = VALUE_OR_RETURN_STATUS(
                 legacy2aidl_audio_session_t_int32_t(audioSession));
         int32_t pidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(pid));
-        return mDelegate->releaseAudioSessionId(audioSessionAidl, pidAidl).transactionError();
+        return statusTFromBinderStatus(
+                mDelegate->releaseAudioSessionId(audioSessionAidl, pidAidl));
     }();
     // Failure is ignored.
 }
 
 status_t AudioFlingerClientAdapter::queryNumberEffects(uint32_t* numEffects) const {
     int32_t aidlRet;
-    RETURN_STATUS_IF_ERROR(mDelegate->queryNumberEffects(&aidlRet).transactionError());
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->queryNumberEffects(&aidlRet)));
     if (numEffects != nullptr) {
         *numEffects = VALUE_OR_RETURN_STATUS(convertIntegral<uint32_t>(aidlRet));
     }
@@ -544,7 +550,8 @@
 AudioFlingerClientAdapter::queryEffect(uint32_t index, effect_descriptor_t* pDescriptor) const {
     int32_t indexAidl = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(index));
     media::EffectDescriptor aidlRet;
-    RETURN_STATUS_IF_ERROR(mDelegate->queryEffect(indexAidl, &aidlRet).transactionError());
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->queryEffect(indexAidl, &aidlRet)));
     if (pDescriptor != nullptr) {
         *pDescriptor = VALUE_OR_RETURN_STATUS(
                 aidl2legacy_EffectDescriptor_effect_descriptor_t(aidlRet));
@@ -563,9 +570,9 @@
     int32_t preferredTypeFlagAidl = VALUE_OR_RETURN_STATUS(
             convertReinterpret<int32_t>(preferredTypeFlag));
     media::EffectDescriptor aidlRet;
-    RETURN_STATUS_IF_ERROR(
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
             mDelegate->getEffectDescriptor(effectUuidAidl, typeUuidAidl, preferredTypeFlagAidl,
-                                           &aidlRet).transactionError());
+                                           &aidlRet)));
     if (pDescriptor != nullptr) {
         *pDescriptor = VALUE_OR_RETURN_STATUS(
                 aidl2legacy_EffectDescriptor_effect_descriptor_t(aidlRet));
@@ -575,7 +582,7 @@
 
 status_t AudioFlingerClientAdapter::createEffect(const media::CreateEffectRequest& request,
                                                  media::CreateEffectResponse* response) {
-    return mDelegate->createEffect(request, response).transactionError();
+    return statusTFromBinderStatus(mDelegate->createEffect(request, response));
 }
 
 status_t
@@ -586,7 +593,8 @@
             legacy2aidl_audio_io_handle_t_int32_t(srcOutput));
     int32_t dstOutputAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_io_handle_t_int32_t(dstOutput));
-    return mDelegate->moveEffects(sessionAidl, srcOutputAidl, dstOutputAidl).transactionError();
+    return statusTFromBinderStatus(
+            mDelegate->moveEffects(sessionAidl, srcOutputAidl, dstOutputAidl));
 }
 
 void AudioFlingerClientAdapter::setEffectSuspended(int effectId,
@@ -596,8 +604,8 @@
         int32_t effectIdAidl = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(effectId));
         int32_t sessionIdAidl = VALUE_OR_RETURN_STATUS(
                 legacy2aidl_audio_session_t_int32_t(sessionId));
-        return mDelegate->setEffectSuspended(effectIdAidl, sessionIdAidl,
-                                             suspended).transactionError();
+        return statusTFromBinderStatus(
+                mDelegate->setEffectSuspended(effectIdAidl, sessionIdAidl, suspended));
     }();
     // Failure is ignored.
 }
@@ -606,7 +614,8 @@
     auto result = [&]() -> ConversionResult<audio_module_handle_t> {
         std::string nameAidl(name);
         int32_t aidlRet;
-        RETURN_IF_ERROR(mDelegate->loadHwModule(nameAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->loadHwModule(nameAidl, &aidlRet)));
         return aidl2legacy_int32_t_audio_module_handle_t(aidlRet);
     }();
     // Failure is ignored.
@@ -616,7 +625,8 @@
 uint32_t AudioFlingerClientAdapter::getPrimaryOutputSamplingRate() {
     auto result = [&]() -> ConversionResult<uint32_t> {
         int32_t aidlRet;
-        RETURN_IF_ERROR(mDelegate->getPrimaryOutputSamplingRate(&aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getPrimaryOutputSamplingRate(&aidlRet)));
         return convertIntegral<uint32_t>(aidlRet);
     }();
     // Failure is ignored.
@@ -626,7 +636,8 @@
 size_t AudioFlingerClientAdapter::getPrimaryOutputFrameCount() {
     auto result = [&]() -> ConversionResult<size_t> {
         int64_t aidlRet;
-        RETURN_IF_ERROR(mDelegate->getPrimaryOutputFrameCount(&aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getPrimaryOutputFrameCount(&aidlRet)));
         return convertIntegral<size_t>(aidlRet);
     }();
     // Failure is ignored.
@@ -634,13 +645,14 @@
 }
 
 status_t AudioFlingerClientAdapter::setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) {
-    return mDelegate->setLowRamDevice(isLowRamDevice, totalMemory).transactionError();
+    return statusTFromBinderStatus(mDelegate->setLowRamDevice(isLowRamDevice, totalMemory));
 }
 
 status_t AudioFlingerClientAdapter::getAudioPort(struct audio_port_v7* port) {
     media::AudioPort portAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_v7_AudioPort(*port));
     media::AudioPort aidlRet;
-    RETURN_STATUS_IF_ERROR(mDelegate->getAudioPort(portAidl, &aidlRet).transactionError());
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->getAudioPort(portAidl, &aidlRet)));
     *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPort_audio_port_v7(aidlRet));
     return OK;
 }
@@ -649,7 +661,8 @@
                                                      audio_patch_handle_t* handle) {
     media::AudioPatch patchAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_AudioPatch(*patch));
     int32_t aidlRet;
-    RETURN_STATUS_IF_ERROR(mDelegate->createAudioPatch(patchAidl, &aidlRet).transactionError());
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->createAudioPatch(patchAidl, &aidlRet)));
     if (handle != nullptr) {
         *handle = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_patch_handle_t(aidlRet));
     }
@@ -658,14 +671,15 @@
 
 status_t AudioFlingerClientAdapter::releaseAudioPatch(audio_patch_handle_t handle) {
     int32_t handleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_handle_t_int32_t(handle));
-    return mDelegate->releaseAudioPatch(handleAidl).transactionError();
+    return statusTFromBinderStatus(mDelegate->releaseAudioPatch(handleAidl));
 }
 
 status_t AudioFlingerClientAdapter::listAudioPatches(unsigned int* num_patches,
                                                      struct audio_patch* patches) {
     std::vector<media::AudioPatch> aidlRet;
     int32_t maxPatches = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*num_patches));
-    RETURN_STATUS_IF_ERROR(mDelegate->listAudioPatches(maxPatches, &aidlRet).transactionError());
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->listAudioPatches(maxPatches, &aidlRet)));
     *num_patches = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(aidlRet.size()));
     return convertRange(aidlRet.begin(), aidlRet.end(), patches,
                         aidl2legacy_AudioPatch_audio_patch);
@@ -674,29 +688,30 @@
 status_t AudioFlingerClientAdapter::setAudioPortConfig(const struct audio_port_config* config) {
     media::AudioPortConfig configAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_port_config_AudioPortConfig(*config));
-    return mDelegate->setAudioPortConfig(configAidl).transactionError();
+    return statusTFromBinderStatus(mDelegate->setAudioPortConfig(configAidl));
 }
 
 audio_hw_sync_t AudioFlingerClientAdapter::getAudioHwSyncForSession(audio_session_t sessionId) {
     auto result = [&]() -> ConversionResult<audio_hw_sync_t> {
         int32_t sessionIdAidl = VALUE_OR_RETURN(legacy2aidl_audio_session_t_int32_t(sessionId));
         int32_t aidlRet;
-        RETURN_IF_ERROR(
-                mDelegate->getAudioHwSyncForSession(sessionIdAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getAudioHwSyncForSession(sessionIdAidl, &aidlRet)));
         return aidl2legacy_int32_t_audio_hw_sync_t(aidlRet);
     }();
     return result.value_or(AUDIO_HW_SYNC_INVALID);
 }
 
 status_t AudioFlingerClientAdapter::systemReady() {
-    return mDelegate->systemReady().transactionError();
+    return statusTFromBinderStatus(mDelegate->systemReady());
 }
 
 size_t AudioFlingerClientAdapter::frameCountHAL(audio_io_handle_t ioHandle) const {
     auto result = [&]() -> ConversionResult<size_t> {
         int32_t ioHandleAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
         int64_t aidlRet;
-        RETURN_IF_ERROR(mDelegate->frameCountHAL(ioHandleAidl, &aidlRet).transactionError());
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->frameCountHAL(ioHandleAidl, &aidlRet)));
         return convertIntegral<size_t>(aidlRet);
     }();
     // Failure is ignored.
@@ -706,7 +721,8 @@
 status_t
 AudioFlingerClientAdapter::getMicrophones(std::vector<media::MicrophoneInfo>* microphones) {
     std::vector<media::MicrophoneInfoData> aidlRet;
-    RETURN_STATUS_IF_ERROR(mDelegate->getMicrophones(&aidlRet).transactionError());
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->getMicrophones(&aidlRet)));
     if (microphones != nullptr) {
         *microphones = VALUE_OR_RETURN_STATUS(
                 convertContainer<std::vector<media::MicrophoneInfo>>(aidlRet,
@@ -718,7 +734,7 @@
 status_t AudioFlingerClientAdapter::setAudioHalPids(const std::vector<pid_t>& pids) {
     std::vector<int32_t> pidsAidl = VALUE_OR_RETURN_STATUS(
             convertContainer<std::vector<int32_t>>(pids, legacy2aidl_pid_t_int32_t));
-    return mDelegate->setAudioHalPids(pidsAidl).transactionError();
+    return statusTFromBinderStatus(mDelegate->setAudioHalPids(pidsAidl));
 }
 
 
diff --git a/media/libaudioclient/PlayerBase.cpp b/media/libaudioclient/PlayerBase.cpp
index c443865..9e7d89e 100644
--- a/media/libaudioclient/PlayerBase.cpp
+++ b/media/libaudioclient/PlayerBase.cpp
@@ -15,13 +15,14 @@
  */
 
 #include <binder/IServiceManager.h>
+#include <media/AidlConversionUtil.h>
 #include <media/PlayerBase.h>
 
 #define max(a, b) ((a) > (b) ? (a) : (b))
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
 namespace android {
-
+using aidl_utils::binderStatusFromStatusT;
 using media::VolumeShaperConfiguration;
 using media::VolumeShaperOperation;
 
@@ -150,7 +151,7 @@
     if (status != NO_ERROR) {
         ALOGW("PlayerBase::setVolume() error %d", status);
     }
-    return binder::Status::fromStatusT(status);
+    return binderStatusFromStatusT(status);
 }
 
 binder::Status PlayerBase::setPan(float pan) {
@@ -170,7 +171,7 @@
     if (status != NO_ERROR) {
         ALOGW("PlayerBase::setPan() error %d", status);
     }
-    return binder::Status::fromStatusT(status);
+    return binderStatusFromStatusT(status);
 }
 
 binder::Status PlayerBase::setStartDelayMs(int32_t delayMs __unused) {
diff --git a/media/libaudioclient/TrackPlayerBase.cpp b/media/libaudioclient/TrackPlayerBase.cpp
index e571838..372b7c3 100644
--- a/media/libaudioclient/TrackPlayerBase.cpp
+++ b/media/libaudioclient/TrackPlayerBase.cpp
@@ -17,7 +17,7 @@
 #include <media/TrackPlayerBase.h>
 
 namespace android {
-
+using aidl_utils::binderStatusFromStatusT;
 using media::VolumeShaper;
 
 //--------------------------------------------------------------------------------------------------
@@ -115,7 +115,7 @@
     status_t s = spConfiguration->readFromParcelable(configuration)
             ?: spOperation->readFromParcelable(operation);
     if (s != OK) {
-        return binder::Status::fromStatusT(s);
+        return binderStatusFromStatusT(s);
     }
 
     if (mAudioTrack != 0) {
@@ -124,7 +124,7 @@
         if (status < 0) { // a non-negative value is the volume shaper id.
             ALOGE("TrackPlayerBase::applyVolumeShaper() failed with status %d", status);
         }
-        return binder::Status::fromStatusT(status);
+        return binderStatusFromStatusT(status);
     } else {
         ALOGD("TrackPlayerBase::applyVolumeShaper()"
               " no AudioTrack for volume control from IPlayer");
diff --git a/media/libaudioclient/include/media/AidlConversionUtil.h b/media/libaudioclient/include/media/AidlConversionUtil.h
index 6bfb743..9453673 100644
--- a/media/libaudioclient/include/media/AidlConversionUtil.h
+++ b/media/libaudioclient/include/media/AidlConversionUtil.h
@@ -21,6 +21,7 @@
 #include <utility>
 
 #include <android-base/expected.h>
+#include <binder/Status.h>
 
 namespace android {
 
@@ -132,4 +133,98 @@
 #define UNION_SET(u, field, value) \
     (u).set<std::decay_t<decltype(u)>::Tag::field>(value)
 
+namespace aidl_utils {
+
+/**
+ * Return the equivalent Android status_t from a binder exception code.
+ *
+ * Generally one should use statusTFromBinderStatus() instead.
+ *
+ * Exception codes can be generated from a remote Java service exception, translate
+ * them for use on the Native side.
+ *
+ * Note: for EX_TRANSACTION_FAILED and EX_SERVICE_SPECIFIC a more detailed error code
+ * can be found from transactionError() or serviceSpecificErrorCode().
+ */
+static inline status_t statusTFromExceptionCode(int32_t exceptionCode) {
+    using namespace ::android::binder;
+    switch (exceptionCode) {
+        case Status::EX_NONE:
+            return OK;
+        case Status::EX_SECURITY: // Java SecurityException, rethrows locally in Java
+            return PERMISSION_DENIED;
+        case Status::EX_BAD_PARCELABLE: // Java BadParcelableException, rethrows in Java
+        case Status::EX_ILLEGAL_ARGUMENT: // Java IllegalArgumentException, rethrows in Java
+        case Status::EX_NULL_POINTER: // Java NullPointerException, rethrows in Java
+            return BAD_VALUE;
+        case Status::EX_ILLEGAL_STATE: // Java IllegalStateException, rethrows in Java
+        case Status::EX_UNSUPPORTED_OPERATION: // Java UnsupportedOperationException, rethrows
+            return INVALID_OPERATION;
+        case Status::EX_HAS_REPLY_HEADER: // Native strictmode violation
+        case Status::EX_PARCELABLE: // Java bootclass loader (not standard exception), rethrows
+        case Status::EX_NETWORK_MAIN_THREAD: // Java NetworkOnMainThreadException, rethrows
+        case Status::EX_TRANSACTION_FAILED: // Native - see error code
+        case Status::EX_SERVICE_SPECIFIC:  // Java ServiceSpecificException,
+                                           // rethrows in Java with integer error code
+            return UNKNOWN_ERROR;
+    }
+    return UNKNOWN_ERROR;
+}
+
+/**
+ * Return the equivalent Android status_t from a binder status.
+ *
+ * Used to handle errors from a AIDL method declaration
+ *
+ * [oneway] void method(type0 param0, ...)
+ *
+ * or the following (where return_type is not a status_t)
+ *
+ * return_type method(type0 param0, ...)
+ */
+static inline status_t statusTFromBinderStatus(const ::android::binder::Status &status) {
+    return status.isOk() ? OK // check OK,
+        : status.serviceSpecificErrorCode() // service-side error, not standard Java exception
+                                            // (fromServiceSpecificError)
+        ?: status.transactionError() // a native binder transaction error (fromStatusT)
+        ?: statusTFromExceptionCode(status.exceptionCode()); // a service-side error with a
+                                                    // standard Java exception (fromExceptionCode)
+}
+
+/**
+ * Return a binder::Status from native service status.
+ *
+ * This is used for methods not returning an explicit status_t,
+ * where Java callers expect an exception, not an integer return value.
+ */
+static inline ::android::binder::Status binderStatusFromStatusT(
+        status_t status, const char *optionalMessage = nullptr) {
+    const char * const emptyIfNull = optionalMessage == nullptr ? "" : optionalMessage;
+    // From binder::Status instructions:
+    //  Prefer a generic exception code when possible, then a service specific
+    //  code, and finally a status_t for low level failures or legacy support.
+    //  Exception codes and service specific errors map to nicer exceptions for
+    //  Java clients.
+
+    using namespace ::android::binder;
+    switch (status) {
+        case OK:
+            return Status::ok();
+        case PERMISSION_DENIED: // throw SecurityException on Java side
+            return Status::fromExceptionCode(Status::EX_SECURITY, emptyIfNull);
+        case BAD_VALUE: // throw IllegalArgumentException on Java side
+            return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, emptyIfNull);
+        case INVALID_OPERATION: // throw IllegalStateException on Java side
+            return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, emptyIfNull);
+    }
+
+    // A service specific error will not show on status.transactionError() so
+    // be sure to use statusTFromBinderStatus() for reliable error handling.
+
+    // throw a ServiceSpecificException.
+    return Status::fromServiceSpecificError(status, emptyIfNull);
+}
+
+} // namespace aidl_utils
+
 }  // namespace android
diff --git a/media/libaudioclient/tests/Android.bp b/media/libaudioclient/tests/Android.bp
index 350a780..21d18d3 100644
--- a/media/libaudioclient/tests/Android.bp
+++ b/media/libaudioclient/tests/Android.bp
@@ -7,6 +7,18 @@
 }
 
 cc_test {
+    name: "audio_aidl_status_tests",
+    defaults: ["libaudioclient_tests_defaults"],
+    srcs: ["audio_aidl_status_tests.cpp"],
+    shared_libs: [
+        "libaudioclient_aidl_conversion",
+        "libbinder",
+        "libcutils",
+        "libutils",
+    ],
+}
+
+cc_test {
     name: "test_create_audiotrack",
     defaults: ["libaudioclient_tests_defaults"],
     srcs: ["test_create_audiotrack.cpp",
diff --git a/media/libaudioclient/tests/audio_aidl_status_tests.cpp b/media/libaudioclient/tests/audio_aidl_status_tests.cpp
new file mode 100644
index 0000000..5517091
--- /dev/null
+++ b/media/libaudioclient/tests/audio_aidl_status_tests.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2020 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
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <media/AidlConversionUtil.h>
+#include <utils/Errors.h>
+
+using namespace android;
+using namespace android::aidl_utils;
+using android::binder::Status;
+
+// Tests for statusTFromBinderStatus() and binderStatusFromStatusT().
+
+// STATUS_T_SMALL_VALUE_LIMIT is an arbitrary limit where we exhaustively check status_t errors.
+// It is known that this limit doesn't cover UNKNOWN_ERROR ~ INT32_MIN.
+constexpr status_t STATUS_T_SMALL_VALUE_LIMIT = -1000;
+
+// Small status values are preserved on round trip
+TEST(audio_aidl_status_tests, statusRoundTripSmallValues) {
+    for (status_t status = 0; status > STATUS_T_SMALL_VALUE_LIMIT; --status) {
+        ASSERT_EQ(status, statusTFromBinderStatus(binderStatusFromStatusT(status)));
+    }
+}
+
+// Special status values are preserved on round trip.
+TEST(audio_aidl_status_tests, statusRoundTripSpecialValues) {
+    for (status_t status : {
+            OK,
+            UNKNOWN_ERROR,
+            NO_MEMORY,
+            INVALID_OPERATION,
+            BAD_VALUE,
+            BAD_TYPE,
+            NAME_NOT_FOUND,
+            PERMISSION_DENIED,
+            NO_INIT,
+            ALREADY_EXISTS,
+            DEAD_OBJECT,
+            FAILED_TRANSACTION,
+            BAD_INDEX,
+            NOT_ENOUGH_DATA,
+            WOULD_BLOCK,
+            TIMED_OUT,
+            UNKNOWN_TRANSACTION,
+            FDS_NOT_ALLOWED}) {
+        ASSERT_EQ(status, statusTFromBinderStatus(binderStatusFromStatusT(status)));
+    }
+}
+
+// Binder exceptions show as an error (not fixed at this time); these come fromExceptionCode().
+TEST(audio_aidl_status_tests, binderStatusExceptions) {
+    for (int exceptionCode : {
+            //Status::EX_NONE,
+            Status::EX_SECURITY,
+            Status::EX_BAD_PARCELABLE,
+            Status::EX_ILLEGAL_ARGUMENT,
+            Status::EX_NULL_POINTER,
+            Status::EX_ILLEGAL_STATE,
+            Status::EX_NETWORK_MAIN_THREAD,
+            Status::EX_UNSUPPORTED_OPERATION,
+            //Status::EX_SERVICE_SPECIFIC, -- tested fromServiceSpecificError()
+            Status::EX_PARCELABLE,
+            // This is special and Java specific; see Parcel.java.
+            Status::EX_HAS_REPLY_HEADER,
+            // This is special, and indicates to C++ binder proxies that the
+            // transaction has failed at a low level.
+            //Status::EX_TRANSACTION_FAILED, -- tested fromStatusT().
+            }) {
+        ASSERT_NE(OK, statusTFromBinderStatus(Status::fromExceptionCode(exceptionCode)));
+    }
+}
+
+// Binder transaction errors show exactly in status_t; these come fromStatusT().
+TEST(audio_aidl_status_tests, binderStatusTransactionError) {
+    for (status_t status : {
+            OK, // Note: fromStatusT does check if this is 0, so this is no error.
+            UNKNOWN_ERROR,
+            NO_MEMORY,
+            INVALID_OPERATION,
+            BAD_VALUE,
+            BAD_TYPE,
+            NAME_NOT_FOUND,
+            PERMISSION_DENIED,
+            NO_INIT,
+            ALREADY_EXISTS,
+            DEAD_OBJECT,
+            FAILED_TRANSACTION,
+            BAD_INDEX,
+            NOT_ENOUGH_DATA,
+            WOULD_BLOCK,
+            TIMED_OUT,
+            UNKNOWN_TRANSACTION,
+            FDS_NOT_ALLOWED}) {
+        ASSERT_EQ(status, statusTFromBinderStatus(Status::fromStatusT(status)));
+    }
+}
+
+// Binder service specific errors show in status_t; these come fromServiceSpecificError().
+TEST(audio_aidl_status_tests, binderStatusServiceSpecificError) {
+    // fromServiceSpecificError() still stores exception code if status is 0.
+    for (status_t status = -1; status > STATUS_T_SMALL_VALUE_LIMIT; --status) {
+        ASSERT_EQ(status, statusTFromBinderStatus(Status::fromServiceSpecificError(status)));
+    }
+}
+
+// Binder status with message.
+TEST(audio_aidl_status_tests, binderStatusMessage) {
+    const String8 message("abcd");
+    for (status_t status = -1; status > STATUS_T_SMALL_VALUE_LIMIT; --status) {
+        const Status binderStatus = binderStatusFromStatusT(status, message.c_str());
+        ASSERT_EQ(status, statusTFromBinderStatus(binderStatus));
+        ASSERT_EQ(message, binderStatus.exceptionMessage());
+    }
+}
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index eaad6ef..3ab7737 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -60,6 +60,7 @@
 
 namespace android {
 
+using aidl_utils::statusTFromBinderStatus;
 using binder::Status;
 
 namespace {
@@ -3027,7 +3028,7 @@
                 bs = handle.second->disable(&status);
             }
             if (!bs.isOk()) {
-              status = bs.transactionError();
+              status = statusTFromBinderStatus(bs);
             }
         }
     }
@@ -3142,7 +3143,7 @@
             bs = (*handle)->disable(&status);
         }
         if (!bs.isOk()) {
-            status = bs.transactionError();
+            status = statusTFromBinderStatus(bs);
         }
     }
     return status;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index e487481..6049f62 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -54,6 +54,7 @@
 
 namespace android {
 
+using aidl_utils::binderStatusFromStatusT;
 using binder::Status;
 using media::VolumeShaper;
 // ----------------------------------------------------------------------------
@@ -2132,7 +2133,7 @@
 binder::Status AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event,
         int /*audio_session_t*/ triggerSession) {
     ALOGV("%s()", __func__);
-    return binder::Status::fromStatusT(
+    return binderStatusFromStatusT(
         mRecordTrack->start((AudioSystem::sync_event_t)event, (audio_session_t) triggerSession));
 }
 
@@ -2155,19 +2156,19 @@
     for (size_t i = 0; status == OK && i < mics.size(); ++i) {
        status = mics[i].writeToParcelable(&activeMicrophones->at(i));
     }
-    return binder::Status::fromStatusT(status);
+    return binderStatusFromStatusT(status);
 }
 
 binder::Status AudioFlinger::RecordHandle::setPreferredMicrophoneDirection(
         int /*audio_microphone_direction_t*/ direction) {
     ALOGV("%s()", __func__);
-    return binder::Status::fromStatusT(mRecordTrack->setPreferredMicrophoneDirection(
+    return binderStatusFromStatusT(mRecordTrack->setPreferredMicrophoneDirection(
             static_cast<audio_microphone_direction_t>(direction)));
 }
 
 binder::Status AudioFlinger::RecordHandle::setPreferredMicrophoneFieldDimension(float zoom) {
     ALOGV("%s()", __func__);
-    return binder::Status::fromStatusT(mRecordTrack->setPreferredMicrophoneFieldDimension(zoom));
+    return binderStatusFromStatusT(mRecordTrack->setPreferredMicrophoneFieldDimension(zoom));
 }
 
 // ----------------------------------------------------------------------------