Merge "Add more logging for analytics dumps"
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index de22352..cda6054 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -2444,6 +2444,7 @@
public Call getHeldCallByConnectionService(ConnectionServiceWrapper connSvr) {
Optional<Call> heldCall = mCalls.stream()
.filter(call -> call.getConnectionService() == connSvr
+ && call.getParentCall() == null
&& call.getState() == CallState.ON_HOLD)
.findFirst();
return heldCall.isPresent() ? heldCall.get() : null;
diff --git a/src/com/android/server/telecom/InCallTonePlayer.java b/src/com/android/server/telecom/InCallTonePlayer.java
index d0afe28..5864ce0 100644
--- a/src/com/android/server/telecom/InCallTonePlayer.java
+++ b/src/com/android/server/telecom/InCallTonePlayer.java
@@ -16,10 +16,13 @@
package com.android.server.telecom;
+import android.annotation.Nullable;
+import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.ToneGenerator;
+import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.telecom.Log;
@@ -87,33 +90,51 @@
public static class MediaPlayerAdapterImpl implements MediaPlayerAdapter {
private MediaPlayer mMediaPlayer;
- public MediaPlayerAdapterImpl(MediaPlayer mediaPlayer) {
+ /**
+ * Create new media player adapter backed by a real mediaplayer.
+ * Note: Its possible for the mediaplayer to be null if
+ * {@link MediaPlayer#create(Context, Uri)} fails for some reason; in this case we can
+ * continue but not bother playing the audio.
+ * @param mediaPlayer The media player.
+ */
+ public MediaPlayerAdapterImpl(@Nullable MediaPlayer mediaPlayer) {
mMediaPlayer = mediaPlayer;
}
@Override
public void setLooping(boolean isLooping) {
- mMediaPlayer.setLooping(isLooping);
+ if (mMediaPlayer != null) {
+ mMediaPlayer.setLooping(isLooping);
+ }
}
@Override
public void setOnCompletionListener(MediaPlayer.OnCompletionListener listener) {
- mMediaPlayer.setOnCompletionListener(listener);
+ if (mMediaPlayer != null) {
+ mMediaPlayer.setOnCompletionListener(listener);
+ }
}
@Override
public void start() {
- mMediaPlayer.start();
+ if (mMediaPlayer != null) {
+ mMediaPlayer.start();
+ }
}
@Override
public void release() {
- mMediaPlayer.release();
+ if (mMediaPlayer != null) {
+ mMediaPlayer.release();
+ }
}
@Override
public int getDuration() {
- return mMediaPlayer.getDuration();
+ if (mMediaPlayer != null) {
+ return mMediaPlayer.getDuration();
+ }
+ return 0;
}
}
diff --git a/src/com/android/server/telecom/ServiceBinder.java b/src/com/android/server/telecom/ServiceBinder.java
index cf5407d..a322a5e 100644
--- a/src/com/android/server/telecom/ServiceBinder.java
+++ b/src/com/android/server/telecom/ServiceBinder.java
@@ -73,13 +73,15 @@
// Reset any abort request if we're asked to bind again.
clearAbort();
- if (!mCallbacks.isEmpty()) {
- // Binding already in progress, append to the list of callbacks and bail out.
+ synchronized (mCallbacks) {
+ if (!mCallbacks.isEmpty()) {
+ // Binding already in progress, append to the list of callbacks and bail out.
+ mCallbacks.add(callback);
+ return;
+ }
mCallbacks.add(callback);
- return;
}
- mCallbacks.add(callback);
if (mServiceConnection == null) {
Intent serviceIntent = new Intent(mServiceAction).setComponent(mComponentName);
ServiceConnection connection = new ServiceBinderConnection(call);
@@ -351,10 +353,16 @@
* outstanding callbacks is cleared afterwards.
*/
private void handleSuccessfulConnection() {
- for (BindCallback callback : mCallbacks) {
+ // Make a copy so that we don't have a deadlock inside one of the callbacks.
+ Set<BindCallback> callbacksCopy = new ArraySet<>();
+ synchronized (mCallbacks) {
+ callbacksCopy.addAll(mCallbacks);
+ mCallbacks.clear();
+ }
+
+ for (BindCallback callback : callbacksCopy) {
callback.onSuccess();
}
- mCallbacks.clear();
}
/**
@@ -362,10 +370,16 @@
* outstanding callbacks is cleared afterwards.
*/
private void handleFailedConnection() {
- for (BindCallback callback : mCallbacks) {
+ // Make a copy so that we don't have a deadlock inside one of the callbacks.
+ Set<BindCallback> callbacksCopy = new ArraySet<>();
+ synchronized (mCallbacks) {
+ callbacksCopy.addAll(mCallbacks);
+ mCallbacks.clear();
+ }
+
+ for (BindCallback callback : callbacksCopy) {
callback.onFailure();
}
- mCallbacks.clear();
}
/**