Merge "Throw IllegalStateException to fail fast in IMS"
diff --git a/telephony/java/android/telephony/ims/ImsUtListener.java b/telephony/java/android/telephony/ims/ImsUtListener.java
index baa0576..754814f 100644
--- a/telephony/java/android/telephony/ims/ImsUtListener.java
+++ b/telephony/java/android/telephony/ims/ImsUtListener.java
@@ -178,4 +178,11 @@
public ImsUtListener(IImsUtListener serviceInterface) {
mServiceInterface = serviceInterface;
}
+
+ /**
+ * @hide
+ */
+ public IImsUtListener getListenerInterface() {
+ return mServiceInterface;
+ }
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java
index 06c35ea..2e35d27 100644
--- a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java
@@ -23,6 +23,8 @@
import com.android.ims.internal.IImsEcbm;
import com.android.ims.internal.IImsEcbmListener;
+import java.util.Objects;
+
/**
* Base implementation of ImsEcbm, which implements stub versions of the methods
* in the IImsEcbm AIDL. Override the methods that your implementation of ImsEcbm supports.
@@ -36,11 +38,27 @@
public class ImsEcbmImplBase {
private static final String TAG = "ImsEcbmImplBase";
+ private final Object mLock = new Object();
private IImsEcbmListener mListener;
- private IImsEcbm mImsEcbm = new IImsEcbm.Stub() {
+ private final IImsEcbm mImsEcbm = new IImsEcbm.Stub() {
@Override
public void setListener(IImsEcbmListener listener) {
- mListener = listener;
+ synchronized (mLock) {
+ if (mImsEcbm != null && listener != null && Objects.equals(
+ mImsEcbm.asBinder(), listener.asBinder())) {
+ return;
+ }
+ if (listener == null) {
+ mListener = null;
+ } else if (listener != null && mListener == null) {
+ mListener = listener;
+ } else {
+ // Fail fast here instead of silently overwriting the listener to another
+ // listener due to another connection connecting.
+ throw new IllegalStateException("ImsEcbmImplBase: Listener already set by "
+ + "another connection.");
+ }
+ }
}
@Override
@@ -69,9 +87,13 @@
*/
public final void enteredEcbm() {
Log.d(TAG, "Entered ECBM.");
- if (mListener != null) {
+ IImsEcbmListener listener;
+ synchronized (mLock) {
+ listener = mListener;
+ }
+ if (listener != null) {
try {
- mListener.enteredECBM();
+ listener.enteredECBM();
} catch (RemoteException e) {
throw new RuntimeException(e);
}
@@ -85,9 +107,13 @@
*/
public final void exitedEcbm() {
Log.d(TAG, "Exited ECBM.");
- if (mListener != null) {
+ IImsEcbmListener listener;
+ synchronized (mLock) {
+ listener = mListener;
+ }
+ if (listener != null) {
try {
- mListener.exitedECBM();
+ listener.exitedECBM();
} catch (RemoteException e) {
throw new RuntimeException(e);
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java
index d002903..555a47e 100644
--- a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java
@@ -25,6 +25,7 @@
import com.android.ims.internal.IImsMultiEndpoint;
import java.util.List;
+import java.util.Objects;
/**
* Base implementation of ImsMultiEndpoint, which implements stub versions of the methods
@@ -41,10 +42,28 @@
private static final String TAG = "MultiEndpointImplBase";
private IImsExternalCallStateListener mListener;
- private IImsMultiEndpoint mImsMultiEndpoint = new IImsMultiEndpoint.Stub() {
+ private final Object mLock = new Object();
+ private final IImsMultiEndpoint mImsMultiEndpoint = new IImsMultiEndpoint.Stub() {
+
@Override
public void setListener(IImsExternalCallStateListener listener) throws RemoteException {
- mListener = listener;
+ synchronized (mLock) {
+ if (mListener != null && listener != null && Objects.equals(
+ mListener.asBinder(), listener.asBinder())) {
+ return;
+ }
+
+ if (listener == null) {
+ mListener = null;
+ } else if (listener != null && mListener == null) {
+ mListener = listener;
+ } else {
+ // Fail fast here instead of silently overwriting the listener to another
+ // listener due to another connection connecting.
+ throw new IllegalStateException("ImsMultiEndpointImplBase: Listener already"
+ + " set by another connection.");
+ }
+ }
}
@Override
@@ -65,9 +84,13 @@
*/
public final void onImsExternalCallStateUpdate(List<ImsExternalCallState> externalCallDialogs) {
Log.d(TAG, "ims external call state update triggered.");
- if (mListener != null) {
+ IImsExternalCallStateListener listener;
+ synchronized (mLock) {
+ listener = mListener;
+ }
+ if (listener != null) {
try {
- mListener.onImsExternalCallStateUpdate(externalCallDialogs);
+ listener.onImsExternalCallStateUpdate(externalCallDialogs);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
index f5219d5..eef4fca 100644
--- a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
@@ -29,6 +29,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
/**
* Base implementation of IMS UT interface, which implements stubs. Override these methods to
@@ -116,7 +117,10 @@
*/
public static final int INVALID_RESULT = -1;
- private IImsUt.Stub mServiceImpl = new IImsUt.Stub() {
+ private final IImsUt.Stub mServiceImpl = new IImsUt.Stub() {
+ private final Object mLock = new Object();
+ private ImsUtListener mUtListener;
+
@Override
public void close() throws RemoteException {
ImsUtImplBase.this.close();
@@ -202,7 +206,26 @@
@Override
public void setListener(IImsUtListener listener) throws RemoteException {
- ImsUtImplBase.this.setListener(new ImsUtListener(listener));
+ synchronized (mLock) {
+ if (mUtListener != null && listener != null && Objects.equals(
+ mUtListener.getListenerInterface().asBinder(), listener.asBinder())) {
+ return;
+ }
+
+ if (listener == null) {
+ mUtListener = null;
+ } else if (listener != null && mUtListener == null) {
+ mUtListener = new ImsUtListener(listener);
+ } else {
+ // This is a limitation of the current API surface, there can only be one
+ // listener connected. Fail fast instead of silently overwriting the other
+ // listener.
+ throw new IllegalStateException("ImsUtImplBase#setListener: listener already "
+ + "set by another connected interface!");
+ }
+ }
+
+ ImsUtImplBase.this.setListener(mUtListener);
}
@Override