diff --git a/telecomm/java/android/telecomm/Call.java b/telecomm/java/android/telecomm/Call.java index a71f739fbc7c6..ecb0d4b7b66e7 100644 --- a/telecomm/java/android/telecomm/Call.java +++ b/telecomm/java/android/telecomm/Call.java @@ -743,6 +743,16 @@ public final class Call { fireStartActivity(intent); } + /** {@hide} */ + final void internalSetDisconnected() { + if (mState != Call.STATE_DISCONNECTED) { + mState = Call.STATE_DISCONNECTED; + fireStateChanged(mState); + fireCallDestroyed(); + mPhone.internalRemoveCall(this); + } + } + private void fireStateChanged(int newState) { for (Listener listener : mListeners) { listener.onStateChanged(this, newState); diff --git a/telecomm/java/android/telecomm/InCallService.java b/telecomm/java/android/telecomm/InCallService.java index a0626320b4bb7..cbcee752098c5 100644 --- a/telecomm/java/android/telecomm/InCallService.java +++ b/telecomm/java/android/telecomm/InCallService.java @@ -163,6 +163,16 @@ public abstract class InCallService extends Service { return new InCallServiceBinder(); } + @Override + public boolean onUnbind(Intent intent) { + Phone oldPhone = mPhone; + mPhone = null; + + oldPhone.destroy(); + onPhoneDestroyed(oldPhone); + return false; + } + /** * Obtain the {@code Phone} associated with this {@code InCallService}. * diff --git a/telecomm/java/android/telecomm/Phone.java b/telecomm/java/android/telecomm/Phone.java index e12534240ec7d..d90d9549802f0 100644 --- a/telecomm/java/android/telecomm/Phone.java +++ b/telecomm/java/android/telecomm/Phone.java @@ -20,7 +20,6 @@ import android.annotation.SystemApi; import android.app.PendingIntent; import android.util.ArrayMap; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -83,7 +82,7 @@ public final class Phone { // A List allows us to keep the Calls in a stable iteration order so that casually developed // user interface components do not incur any spurious jank - private final List mCalls = new ArrayList<>(); + private final List mCalls = new CopyOnWriteArrayList<>(); // An unmodifiable view of the above List can be safely shared with subclass implementations private final List mUnmodifiableCalls = Collections.unmodifiableList(mCalls); @@ -159,6 +158,18 @@ public final class Phone { } } + /** + * Called to destroy the phone and cleanup any lingering calls. + * @hide + */ + final void destroy() { + for (Call call : mCalls) { + if (call.getState() != Call.STATE_DISCONNECTED) { + call.internalSetDisconnected(); + } + } + } + /** * Adds a listener to this {@code Phone}. *