Merge "AudioService: handle errors when reconnecting mixes after server crash"

This commit is contained in:
Treehugger Robot
2019-10-23 16:40:09 +00:00
committed by Gerrit Code Review
4 changed files with 77 additions and 12 deletions

View File

@@ -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
*/

View File

@@ -853,6 +853,10 @@ public class AudioPolicy {
Log.v(TAG, "notifyVolumeAdjust: " + adjustment);
}
}
public void notifyUnregistration() {
setRegistration(null);
}
};
//==================================================

View File

@@ -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();
}

View File

@@ -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);