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

Commit 4e183bbf authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Adds helper method for determining if an mmtel capability is supported

Bug: 141457496
Bug: 122098288
Test: atest FrameworksTelephonyTests
Merged-In: Ia08caaa1ae6f0e68574277fd1c052856a0d8189d
Change-Id: Ia08caaa1ae6f0e68574277fd1c052856a0d8189d
parent d6558e08
Loading
Loading
Loading
Loading
+108 −49
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
@@ -31,6 +32,7 @@ import android.os.ServiceManager;
import android.os.SystemProperties;
import android.provider.Settings;
import android.telecom.TelecomManager;
import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
import android.telephony.ims.ImsMmTelManager;
import android.telephony.ims.ImsService;
@@ -38,6 +40,7 @@ import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsConfigCallback;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.telephony.ims.stub.ImsCallSessionImplBase;
import android.telephony.ims.stub.ImsConfigImplBase;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.telephony.Rlog;
@@ -71,6 +74,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
 * Provides APIs for IMS services, such as initiating IMS calls, and provides access to
@@ -100,9 +104,12 @@ public class ImsManager implements IFeatureConnector {
    public static final int INCOMING_CALL_RESULT_CODE = 101;

    /**
     * Key to retrieve the call ID from an incoming call intent.
     * @see #open(MmTelFeature.Listener)
     * Key to retrieve the call ID from an incoming call intent. No longer used, see
     * {@link ImsCallSessionImplBase#getCallId()}.
     * @deprecated Not used in the framework, keeping around symbol to not break old vendor
     * components.
     */
    @Deprecated
    public static final String EXTRA_CALL_ID = "android:imsCallID";

    /**
@@ -152,7 +159,9 @@ public class ImsManager implements IFeatureConnector {
     * An integer value; service identifier obtained from {@link ImsManager#open}.
     * Internal use only.
     * @hide
     * @deprecated Not used in the system, keeping around to not break old vendor components.
     */
    @Deprecated
    public static final String EXTRA_SERVICE_ID = "android:imsServiceId";

    /**
@@ -160,6 +169,8 @@ public class ImsManager implements IFeatureConnector {
     * An boolean value; Flag to indicate that the incoming call is a normal call or call for USSD.
     * The value "true" indicates that the incoming call is for USSD.
     * Internal use only.
     * @deprecated Keeping around to not break old vendor components. Use
     * {@link MmTelFeature#EXTRA_USSD} instead.
     * @hide
     */
    public static final String EXTRA_USSD = "android:ussd";
@@ -172,6 +183,8 @@ public class ImsManager implements IFeatureConnector {
     * Even though they are not incoming calls, they are propagated
     * to Phone app using same ACTION_IMS_INCOMING_CALL intent.
     * Internal use only.
     * @deprecated Keeping around to not break old vendor components. Use
     * {@link MmTelFeature#EXTRA_IS_UNKNOWN_CALL} instead.
     * @hide
     */
    public static final String EXTRA_IS_UNKNOWN_CALL = "android:isUnknown";
@@ -191,9 +204,24 @@ public class ImsManager implements IFeatureConnector {
        void executeRunnable(Runnable runnable);
    }

    private static class ImsExecutorFactory implements ExecutorFactory {

        private final HandlerThread mThreadHandler;

        public ImsExecutorFactory() {
            mThreadHandler = new HandlerThread("ImsHandlerThread");
            mThreadHandler.start();
        }

        @Override
        public void executeRunnable(Runnable runnable) {
            mThreadHandler.getThreadHandler().post(runnable);
        }
    }

    // Replaced with single-threaded executor for testing.
    @VisibleForTesting
    public ExecutorFactory mExecutorFactory = runnable -> new Thread(runnable).start();
    public ExecutorFactory mExecutorFactory = new ImsExecutorFactory();

    private static HashMap<Integer, ImsManager> sImsManagerInstances =
            new HashMap<Integer, ImsManager>();
@@ -410,6 +438,59 @@ public class ImsManager implements IFeatureConnector {
        return false;
    }

    /**
     * Asynchronous call to ImsService to determine whether or not a specific MmTel capability is
     * supported.
     */
    public void isSupported(int capability, int transportType, Consumer<Boolean> result) {
        mExecutorFactory.executeRunnable(() -> {
            switch(transportType) {
                case (AccessNetworkConstants.TRANSPORT_TYPE_WWAN): {
                    switch (capability) {
                        case (MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE): {
                            result.accept(isVolteEnabledByPlatform());
                            return;
                        } case (MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO): {
                            result.accept(isVtEnabledByPlatform());
                            return;
                        }case (MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT): {
                            result.accept(isSuppServicesOverUtEnabledByPlatform());
                            return;
                        } case (MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS): {
                            // There is currently no carrier config defined for this.
                            result.accept(true);
                            return;
                        }
                    }
                    break;
                } case (AccessNetworkConstants.TRANSPORT_TYPE_WLAN): {
                    switch (capability) {
                        case (MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE) : {
                            result.accept(isWfcEnabledByPlatform());
                            return;
                        } case (MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO) : {
                            // This is not transport dependent at this time.
                            result.accept(isVtEnabledByPlatform());
                            return;
                        } case (MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT) : {
                            // This is not transport dependent at this time.
                            result.accept(isSuppServicesOverUtEnabledByPlatform());
                            return;
                        } case (MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS) : {
                            // There is currently no carrier config defined for this.
                            result.accept(true);
                            return;
                        }
                    }
                    break;
                }
            }
            // false for unknown capability/transport types.
            result.accept(false);
        });

    }

    /**
     * Returns a platform configuration for VoLTE which may override the user setting on a per Slot
     * basis.
@@ -1480,12 +1561,10 @@ public class ImsManager implements IFeatureConnector {
     * (from ISIM) periodically in order to receive calls from the operator's network.
     * When the IMS service receives a new call, it will call
     * {@link MmTelFeature.Listener#onIncomingCall}
     * The listener contains a call ID extra {@link #getCallId} and it can be used to take a call.
     * @param listener A {@link MmTelFeature.Listener}, which is the interface the
     * {@link MmTelFeature} uses to notify the framework of updates
     * @throws NullPointerException if {@code listener} is null
     * @throws ImsException if calling the IMS service results in an error
     * @see #getCallId
     */
    public void open(MmTelFeature.Listener listener) throws ImsException {
        checkAndThrowExceptionIfServiceUnavailable();
@@ -1849,32 +1928,13 @@ public class ImsManager implements IFeatureConnector {
    /**
     * Creates a {@link ImsCall} to take an incoming call.
     *
     * @param sessionId a session id which is obtained from {@link ImsManager#open}
     * @param incomingCallExtras the incoming call broadcast intent
     * @param listener to listen to the call events from {@link ImsCall}
     * @return a {@link ImsCall} object
     * @throws ImsException if calling the IMS service results in an error
     */
    public ImsCall takeCall(IImsCallSession session, Bundle incomingCallExtras,
            ImsCall.Listener listener) throws ImsException {
        if (DBG) {
            log("takeCall :: incomingCall=" + incomingCallExtras);
        }

    public ImsCall takeCall(IImsCallSession session, ImsCall.Listener listener)
            throws ImsException {
        checkAndThrowExceptionIfServiceUnavailable();

        if (incomingCallExtras == null) {
            throw new ImsException("Can't retrieve session with null intent",
                    ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
        }

        String callId = getCallId(incomingCallExtras);

        if (callId == null) {
            throw new ImsException("Call ID missing in the incoming call intent",
                    ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
        }

        try {
            if (session == null) {
                throw new ImsException("No pending session for the call",
@@ -2106,6 +2166,17 @@ public class ImsManager implements IFeatureConnector {
        return mMmTelFeatureConnection.getFeatureState();
    }

    public void getImsServiceState(Consumer<Integer> result) {
        mExecutorFactory.executeRunnable(() -> {
            try {
                result.accept(getImsServiceState());
            } catch (ImsException e) {
                // In the case that the ImsService is not available, report unavailable.
                result.accept(ImsFeature.STATE_UNAVAILABLE);
            }
        });
    }

    private Executor getThreadExecutor() {
        if (Looper.myLooper() == null) {
            Looper.prepare();
@@ -2153,20 +2224,6 @@ public class ImsManager implements IFeatureConnector {
        }
    }

    /**
     * Gets the call ID from the specified incoming call broadcast intent.
     *
     * @param incomingCallExtras the incoming call broadcast intent
     * @return the call ID or null if the intent does not contain it
     */
    private static String getCallId(Bundle incomingCallExtras) {
        if (incomingCallExtras == null) {
            return null;
        }

        return incomingCallExtras.getString(EXTRA_CALL_ID);
    }

    /**
     * Checks to see if the ImsService Binder is connected. If it is not, we try to create the
     * connection again.
@@ -2486,31 +2543,33 @@ public class ImsManager implements IFeatureConnector {
            // Set VoLTE to default
            SubscriptionManager.setSubscriptionProperty(subId,
                    SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
                    booleanToPropertyString(getBooleanCarrierConfig(
                            CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL)));
                    Integer.toString(SUB_PROPERTY_NOT_INITIALIZED));

            // Set VoWiFi to default
            SubscriptionManager.setSubscriptionProperty(subId,
                    SubscriptionManager.WFC_IMS_ENABLED,
                    booleanToPropertyString(getBooleanCarrierConfig(
                            CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL)));
                    Integer.toString(SUB_PROPERTY_NOT_INITIALIZED));

            // Set VoWiFi mode to default
            SubscriptionManager.setSubscriptionProperty(subId,
                    SubscriptionManager.WFC_IMS_MODE,
                    Integer.toString(getIntCarrierConfig(
                            CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT)));
                    Integer.toString(SUB_PROPERTY_NOT_INITIALIZED));

            // Set VoWiFi roaming to default
            SubscriptionManager.setSubscriptionProperty(subId,
                    SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
                    booleanToPropertyString(getBooleanCarrierConfig(
                            CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL)));
                    Integer.toString(SUB_PROPERTY_NOT_INITIALIZED));

            // Set VoWiFi roaming mode to default
            SubscriptionManager.setSubscriptionProperty(subId,
                    SubscriptionManager.WFC_IMS_ROAMING_MODE,
                    Integer.toString(SUB_PROPERTY_NOT_INITIALIZED));


            // Set VT to default
            SubscriptionManager.setSubscriptionProperty(subId,
                    SubscriptionManager.VT_IMS_ENABLED, booleanToPropertyString(true));
                    SubscriptionManager.VT_IMS_ENABLED,
                    Integer.toString(SUB_PROPERTY_NOT_INITIALIZED));
        } else {
            loge("factoryReset: invalid sub id, can not reset siminfo db settings; subId=" + subId);
        }