diff options
| author | 2019-10-23 09:57:49 -0700 | |
|---|---|---|
| committer | 2019-10-23 09:57:49 -0700 | |
| commit | 933083b88c6877d6b9181ee8059c269ec22e10cd (patch) | |
| tree | 16f02a42edfb42e7769b7f85f0f2cc2a078d73c7 | |
| parent | e399a7f82495dd9d8eff4ca5365e3e7efa424b93 (diff) | |
| parent | 0ac7e561e92d9335a5174542abca8ca36f514d11 (diff) | |
Merge "AudioService: handle errors when reconnecting mixes after server crash"
am: 0ac7e561e9
Change-Id: Iceadb2d9f5415ddc004cea99e2ae9c3800e1734b
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); |