Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eca79910 authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Notify ImsService Status Correctly

Modifies ImsService to allow multiple status callbacks in
for one ImsFeature. This better handles one ImsFeature
for normal/emergency calling.

Bug: 38001858
Test: Unit Testing
Merged-In: I70ae6f5349aef75aa86d54fe37a3c32459ea3afa
Change-Id: I70ae6f5349aef75aa86d54fe37a3c32459ea3afa
parent c3013394
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -105,10 +105,11 @@ public abstract class ImsService extends ImsServiceBase {
        }

        @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);
            }
        }

@@ -355,7 +356,7 @@ public abstract class ImsService extends ImsServiceBase {
        if (f != null) {
            f.setContext(this);
            f.setSlotId(slotId);
            f.setImsFeatureStatusCallback(c);
            f.addImsFeatureStatusCallback(c);
            featureMap.put(featureType, f);
        }

@@ -368,7 +369,8 @@ public abstract class ImsService extends ImsServiceBase {
     * 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;
@@ -379,7 +381,7 @@ public abstract class ImsService extends ImsServiceBase {
            featureMap.remove(featureType);
            featureToRemove.notifyFeatureRemoved(slotId);
            // Remove reference to Binder
            featureToRemove.setImsFeatureStatusCallback(null);
            featureToRemove.removeImsFeatureStatusCallback(c);
        }
    }

+41 −13
Original line number Diff line number Diff line
@@ -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;
    public void addImsFeatureStatusCallback(IImsFeatureStatusCallback c) {
        if (c == null) {
            return;
        }
        try {
            // If we have just connected, send queued status.
        notifyFeatureState(mState);
            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,15 +171,20 @@ public abstract class ImsFeature {
     * @param state
     */
    private void notifyFeatureState(@ImsState int state) {
        if (mStatusCallback != null) {
        synchronized (mStatusCallbacks) {
            for (Iterator<IImsFeatureStatusCallback> iter = mStatusCallbacks.iterator();
                 iter.hasNext(); ) {
                IImsFeatureStatusCallback callback = iter.next();
                try {
                    Log.i(LOG_TAG, "notifying ImsFeatureState=" + state);
                mStatusCallback.notifyImsFeatureStatus(state);
                    callback.notifyImsFeatureStatus(state);
                } catch (RemoteException e) {
                mStatusCallback = null;
                    // remove if the callback is no longer alive.
                    iter.remove();
                    Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
                }
            }
        }
        sendImsServiceIntent(state);
    }

+1 −1
Original line number Diff line number Diff line
@@ -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);