Merge "Notify ImsService Status Correctly"

This commit is contained in:
Brad Ebinger
2017-05-10 23:00:52 +00:00
committed by Gerrit Code Review
3 changed files with 49 additions and 19 deletions

View File

@@ -105,10 +105,11 @@ public abstract class ImsService extends ImsServiceBase {
} }
@Override @Override
public void removeImsFeature(int slotId, int feature) throws RemoteException { public void removeImsFeature(int slotId, int feature, IImsFeatureStatusCallback c)
throws RemoteException {
synchronized (mFeatures) { synchronized (mFeatures) {
enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "removeImsFeature"); enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "removeImsFeature");
onRemoveImsFeatureInternal(slotId, feature); onRemoveImsFeatureInternal(slotId, feature, c);
} }
} }
@@ -355,7 +356,7 @@ public abstract class ImsService extends ImsServiceBase {
if (f != null) { if (f != null) {
f.setContext(this); f.setContext(this);
f.setSlotId(slotId); f.setSlotId(slotId);
f.setImsFeatureStatusCallback(c); f.addImsFeatureStatusCallback(c);
featureMap.put(featureType, f); featureMap.put(featureType, f);
} }
@@ -368,7 +369,8 @@ public abstract class ImsService extends ImsServiceBase {
* defined in {@link ImsFeature}. * defined in {@link ImsFeature}.
*/ */
// Be sure to lock on mFeatures before accessing this method // 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); SparseArray<ImsFeature> featureMap = mFeatures.get(slotId);
if (featureMap == null) { if (featureMap == null) {
return; return;
@@ -379,7 +381,7 @@ public abstract class ImsService extends ImsServiceBase {
featureMap.remove(featureType); featureMap.remove(featureType);
featureToRemove.notifyFeatureRemoved(slotId); featureToRemove.notifyFeatureRemoved(slotId);
// Remove reference to Binder // Remove reference to Binder
featureToRemove.setImsFeatureStatusCallback(null); featureToRemove.removeImsFeatureStatusCallback(c);
} }
} }

View File

@@ -28,7 +28,11 @@ import com.android.ims.internal.IImsFeatureStatusCallback;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.WeakHashMap;
/** /**
* Base class for all IMS features that are supported by the framework. * 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; public static final int STATE_READY = 2;
private List<INotifyFeatureRemoved> mRemovedListeners = new ArrayList<>(); 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 @ImsState int mState = STATE_NOT_AVAILABLE;
private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX; private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
private Context mContext; private Context mContext;
@@ -136,11 +141,29 @@ public abstract class ImsFeature {
} }
} }
// Not final for testing. public void addImsFeatureStatusCallback(IImsFeatureStatusCallback c) {
public void setImsFeatureStatusCallback(IImsFeatureStatusCallback c) { if (c == null) {
mStatusCallback = c; return;
// If we have just connected, send queued status. }
notifyFeatureState(mState); 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 * @param state
*/ */
private void notifyFeatureState(@ImsState int state) { private void notifyFeatureState(@ImsState int state) {
if (mStatusCallback != null) { synchronized (mStatusCallbacks) {
try { for (Iterator<IImsFeatureStatusCallback> iter = mStatusCallbacks.iterator();
Log.i(LOG_TAG, "notifying ImsFeatureState=" + state); iter.hasNext(); ) {
mStatusCallback.notifyImsFeatureStatus(state); IImsFeatureStatusCallback callback = iter.next();
} catch (RemoteException e) { try {
mStatusCallback = null; Log.i(LOG_TAG, "notifying ImsFeatureState=" + state);
Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage()); 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); sendImsServiceIntent(state);

View File

@@ -37,7 +37,7 @@ import android.os.Message;
interface IImsServiceController { interface IImsServiceController {
// ImsService Control // ImsService Control
void createImsFeature(int slotId, int feature, IImsFeatureStatusCallback c); void createImsFeature(int slotId, int feature, IImsFeatureStatusCallback c);
void removeImsFeature(int slotId, int feature); void removeImsFeature(int slotId, int feature, IImsFeatureStatusCallback c);
// MMTel Feature // MMTel Feature
int startSession(int slotId, int featureType, in PendingIntent incomingCallIntent, int startSession(int slotId, int featureType, in PendingIntent incomingCallIntent,
in IImsRegistrationListener listener); in IImsRegistrationListener listener);