Fix issue 3435692
The problem is that the AudioService is not notified of the death of
IAudioFlinger binder interface because no methods was called on AudioFlinger
from system_server since the device booted. Therefore, AudioSystem did not created any
IAudioFlinger interface in the system_server process.
The root cause was always present but more likely to happen on a tablet than on a phone
as for instance no beeps are played when volume is adjusted.
The fix consists in having AudioSystem explicitly call a method on AudioFlinger when a
callback is installed to make sure that an IAudioFlinger binder interface is created
regardless of any other activity in the client process.
Change-Id: I9df34a36825af0b25cd0246dd02edbd712263f41
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 6c85490..1fe3ccc 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -1945,10 +1945,11 @@
break;
case MSG_MEDIA_SERVER_DIED:
- // Force creation of new IAudioflinger interface
if (!mMediaServerOk) {
Log.e(TAG, "Media server died.");
- AudioSystem.isMicrophoneMuted();
+ // Force creation of new IAudioFlinger interface so that we are notified
+ // when new media_server process is back to life.
+ AudioSystem.setErrorCallback(mAudioSystemCallback);
sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SHARED_MSG, SENDMSG_NOOP, 0, 0,
null, 500);
}
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index e20bb25..ca881af 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -218,13 +218,26 @@
*/
public static void setErrorCallback(ErrorCallback cb)
{
- mErrorCallback = cb;
+ synchronized (AudioSystem.class) {
+ mErrorCallback = cb;
+ }
+ // Calling a method on AudioFlinger here makes sure that we bind to IAudioFlinger
+ // binder interface death. Not doing that would result in not being notified of
+ // media_server process death if no other method is called on AudioSystem that reaches
+ // to AudioFlinger.
+ isMicrophoneMuted();
}
private static void errorCallbackFromNative(int error)
{
- if (mErrorCallback != null) {
- mErrorCallback.onError(error);
+ ErrorCallback errorCallback = null;
+ synchronized (AudioSystem.class) {
+ if (mErrorCallback != null) {
+ errorCallback = mErrorCallback;
+ }
+ }
+ if (errorCallback != null) {
+ errorCallback.onError(error);
}
}