diff options
author | Jean-Michel Trivi <jmtrivi@google.com> | 2019-10-22 08:59:36 -0700 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2019-10-23 08:22:00 -0700 |
commit | d497edd97936fefc2ad472c05dc920947c588ec4 (patch) | |
tree | 1d73b5a1c9de512b3454e760e4af75398f440789 | |
parent | 81852c8481f555c9ad396aa866442a7669441875 (diff) | |
download | base-d497edd97936fefc2ad472c05dc920947c588ec4.tar.gz |
AudioService: handle errors when reconnecting mixes after server crash
Log errors when reconnecting dynamic policy mixes after an audio
server crash.
Add IntDef for AudioSystem errors, and conversion to String.
Add support for notifying an AudioPolicy user that it was
unregistered.
Bug: 133279309
Test: connect DAP, kill audio server, verify no errors reported
Change-Id: I1dbfdac1873ed9c44c20ca9d25bbe01ce9904ee5
Merged-In: I1dbfdac1873ed9c44c20ca9d25bbe01ce9904ee5
4 files changed, 77 insertions, 12 deletions
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 53bc65d711b0..bb731a8189f9 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -16,6 +16,7 @@ package android.media; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; @@ -26,6 +27,8 @@ import android.media.audiofx.AudioEffect; import android.media.audiopolicy.AudioMix; import android.util.Log; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Map; @@ -431,6 +434,50 @@ public class AudioSystem public static final int DEAD_OBJECT = -6; public static final int WOULD_BLOCK = -7; + /** @hide */ + @IntDef({ + SUCCESS, + ERROR, + BAD_VALUE, + INVALID_OPERATION, + PERMISSION_DENIED, + NO_INIT, + DEAD_OBJECT, + WOULD_BLOCK + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AudioSystemError {} + + /** + * Convert an int error value to its String value for readability. + * Accepted error values are the java AudioSystem errors, matching android_media_AudioErrors.h, + * which map onto the native status_t type. + * @param error one of the java AudioSystem errors + * @return a human-readable string + */ + public static String audioSystemErrorToString(@AudioSystemError int error) { + switch(error) { + case SUCCESS: + return "SUCCESS"; + case ERROR: + return "ERROR"; + case BAD_VALUE: + return "BAD_VALUE"; + case INVALID_OPERATION: + return "INVALID_OPERATION"; + case PERMISSION_DENIED: + return "PERMISSION_DENIED"; + case NO_INIT: + return "NO_INIT"; + case DEAD_OBJECT: + return "DEAD_OBJECT"; + case WOULD_BLOCK: + return "WOULD_BLOCK"; + default: + return ("unknown error:" + error); + } + } + /* * AudioPolicyService methods */ diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java index 39474e13a2d0..01f12500b77b 100644 --- a/media/java/android/media/audiopolicy/AudioPolicy.java +++ b/media/java/android/media/audiopolicy/AudioPolicy.java @@ -853,6 +853,10 @@ public class AudioPolicy { Log.v(TAG, "notifyVolumeAdjust: " + adjustment); } } + + public void notifyUnregistration() { + setRegistration(null); + } }; //================================================== diff --git a/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl b/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl index 107e7cd59ca2..1d581516e7b1 100644 --- a/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl +++ b/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl @@ -34,4 +34,8 @@ oneway interface IAudioPolicyCallback { // callback for volume events void notifyVolumeAdjust(int adjustment); + + // callback for unregistration (e.g. if policy couldn't automatically be re-registered after + // an audioserver crash) + void notifyUnregistration(); } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index e26cbc4487f9..055a4bde8a78 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -1018,7 +1018,14 @@ public class AudioService extends IAudioService.Stub synchronized (mAudioPolicies) { for (AudioPolicyProxy policy : mAudioPolicies.values()) { - policy.connectMixes(); + final int status = policy.connectMixes(); + if (status != AudioSystem.SUCCESS) { + // note that PERMISSION_DENIED may also indicate trouble getting to APService + Log.e(TAG, "onAudioServerDied: error " + + AudioSystem.audioSystemErrorToString(status) + + " when connecting mixes for policy " + policy.toLogFriendlyString()); + policy.release(); + } } } @@ -7007,16 +7014,8 @@ public class AudioService extends IAudioService.Stub } public void binderDied() { - synchronized (mAudioPolicies) { - Log.i(TAG, "audio policy " + mPolicyCallback + " died"); - release(); - mAudioPolicies.remove(mPolicyCallback.asBinder()); - } - if (mIsVolumeController) { - synchronized (mExtVolumeControllerLock) { - mExtVolumeController = null; - } - } + Log.i(TAG, "audio policy " + mPolicyCallback + " died"); + release(); } String getRegistrationId() { @@ -7040,9 +7039,20 @@ public class AudioService extends IAudioService.Stub Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection"); } } + if (mIsVolumeController) { + synchronized (mExtVolumeControllerLock) { + mExtVolumeController = null; + } + } final long identity = Binder.clearCallingIdentity(); AudioSystem.registerPolicyMixes(mMixes, false); Binder.restoreCallingIdentity(identity); + synchronized (mAudioPolicies) { + mAudioPolicies.remove(mPolicyCallback.asBinder()); + } + try { + mPolicyCallback.notifyUnregistration(); + } catch (RemoteException e) { } } boolean hasMixAffectingUsage(int usage, int excludedFlags) { @@ -7093,7 +7103,7 @@ public class AudioService extends IAudioService.Stub } } - int connectMixes() { + @AudioSystem.AudioSystemError int connectMixes() { final long identity = Binder.clearCallingIdentity(); int status = AudioSystem.registerPolicyMixes(mMixes, true); Binder.restoreCallingIdentity(identity); |