diff options
| author | 2017-05-10 20:42:34 +0000 | |
|---|---|---|
| committer | 2017-05-10 20:42:38 +0000 | |
| commit | 9684d718faf3bf2c8df258be8fdedb32e2a29db0 (patch) | |
| tree | f4dc70b4e4dc66eb087cc13cbb781ed29bc30bd9 | |
| parent | be0078f01827bcd4325166731a065b177572e73c (diff) | |
| parent | e1b49b76540c3c63878eb0d9bd875ac7069b22c3 (diff) | |
Merge "Notify ImsService Status Correctly" into oc-dev
3 files changed, 49 insertions, 19 deletions
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java index ba70374edb7b..9d91cc3387e2 100644 --- a/telephony/java/android/telephony/ims/ImsService.java +++ b/telephony/java/android/telephony/ims/ImsService.java @@ -111,10 +111,11 @@ public class ImsService extends Service { } @Override - public void removeImsFeature(int slotId, int feature) throws RemoteException { + public void removeImsFeature(int slotId, int feature, IImsFeatureStatusCallback c) + throws RemoteException { synchronized (mFeatures) { enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "removeImsFeature"); - onRemoveImsFeatureInternal(slotId, feature); + onRemoveImsFeatureInternal(slotId, feature, c); } } @@ -364,7 +365,7 @@ public class ImsService extends Service { if (f != null) { f.setContext(this); f.setSlotId(slotId); - f.setImsFeatureStatusCallback(c); + f.addImsFeatureStatusCallback(c); featureMap.put(featureType, f); } @@ -377,7 +378,8 @@ public class ImsService extends Service { * defined in {@link ImsFeature}. */ // Be sure to lock on mFeatures before accessing this method - private void onRemoveImsFeatureInternal(int slotId, int featureType) { + private void onRemoveImsFeatureInternal(int slotId, int featureType, + IImsFeatureStatusCallback c) { SparseArray<ImsFeature> featureMap = mFeatures.get(slotId); if (featureMap == null) { return; @@ -388,7 +390,7 @@ public class ImsService extends Service { featureMap.remove(featureType); featureToRemove.notifyFeatureRemoved(slotId); // Remove reference to Binder - featureToRemove.setImsFeatureStatusCallback(null); + featureToRemove.removeImsFeatureStatusCallback(c); } } diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java index 395f1ccc7a29..9d880b7395ef 100644 --- a/telephony/java/android/telephony/ims/feature/ImsFeature.java +++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java @@ -28,7 +28,11 @@ import com.android.ims.internal.IImsFeatureStatusCallback; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.Set; +import java.util.WeakHashMap; /** * Base class for all IMS features that are supported by the framework. @@ -88,7 +92,8 @@ public abstract class ImsFeature { public static final int STATE_READY = 2; private List<INotifyFeatureRemoved> mRemovedListeners = new ArrayList<>(); - private IImsFeatureStatusCallback mStatusCallback; + private final Set<IImsFeatureStatusCallback> mStatusCallbacks = Collections.newSetFromMap( + new WeakHashMap<IImsFeatureStatusCallback, Boolean>()); private @ImsState int mState = STATE_NOT_AVAILABLE; private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX; private Context mContext; @@ -136,11 +141,29 @@ public abstract class ImsFeature { } } - // Not final for testing. - public void setImsFeatureStatusCallback(IImsFeatureStatusCallback c) { - mStatusCallback = c; - // If we have just connected, send queued status. - notifyFeatureState(mState); + public void addImsFeatureStatusCallback(IImsFeatureStatusCallback c) { + if (c == null) { + return; + } + try { + // If we have just connected, send queued status. + c.notifyImsFeatureStatus(mState); + // Add the callback if the callback completes successfully without a RemoteException. + synchronized (mStatusCallbacks) { + mStatusCallbacks.add(c); + } + } catch (RemoteException e) { + Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage()); + } + } + + public void removeImsFeatureStatusCallback(IImsFeatureStatusCallback c) { + if (c == null) { + return; + } + synchronized (mStatusCallbacks) { + mStatusCallbacks.remove(c); + } } /** @@ -148,13 +171,18 @@ public abstract class ImsFeature { * @param state */ private void notifyFeatureState(@ImsState int state) { - if (mStatusCallback != null) { - try { - Log.i(LOG_TAG, "notifying ImsFeatureState=" + state); - mStatusCallback.notifyImsFeatureStatus(state); - } catch (RemoteException e) { - mStatusCallback = null; - Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage()); + synchronized (mStatusCallbacks) { + for (Iterator<IImsFeatureStatusCallback> iter = mStatusCallbacks.iterator(); + iter.hasNext(); ) { + IImsFeatureStatusCallback callback = iter.next(); + try { + Log.i(LOG_TAG, "notifying ImsFeatureState=" + state); + callback.notifyImsFeatureStatus(state); + } catch (RemoteException e) { + // remove if the callback is no longer alive. + iter.remove(); + Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage()); + } } } sendImsServiceIntent(state); diff --git a/telephony/java/com/android/ims/internal/IImsServiceController.aidl b/telephony/java/com/android/ims/internal/IImsServiceController.aidl index 712816f9d20c..bb06d7e085a7 100644 --- a/telephony/java/com/android/ims/internal/IImsServiceController.aidl +++ b/telephony/java/com/android/ims/internal/IImsServiceController.aidl @@ -37,7 +37,7 @@ import android.os.Message; interface IImsServiceController { // ImsService Control void createImsFeature(int slotId, int feature, IImsFeatureStatusCallback c); - void removeImsFeature(int slotId, int feature); + void removeImsFeature(int slotId, int feature, IImsFeatureStatusCallback c); // MMTel Feature int startSession(int slotId, int featureType, in PendingIntent incomingCallIntent, in IImsRegistrationListener listener); |