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

Commit 2d1d1af2 authored by Xin Li's avatar Xin Li
Browse files

Merge sc-dev-plus-aosp-without-vendor@7634622

Merged-In: Ide6ee346afdd6f9f0bca90a22465fd0d76af8b6a
Change-Id: I854661d3c39b306d304c2b74724d802312555bf5
parents cc40c149 ca78a01f
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -3859,6 +3859,24 @@ public class ImsCall implements ICall {
        }
    }

    /**
     * Determines if the current call is a cross sim call
     * Note: This depends on the RIL exposing the
     * {@link ImsCallProfile#EXTRA_IS_CROSS_SIM_CALL} extra.
     *
     * @return {@code true} if the call is Cross SIM, {@code false} otherwise.
     */
    public boolean isCrossSimCall() {
        synchronized(mLockObj) {
            if (mCallProfile == null) {
                return false;
            }
            return mCallProfile.getCallExtraBoolean(
                    ImsCallProfile.EXTRA_IS_CROSS_SIM_CALL,
                    false);
        }
    }

    /**
     * Log a string to the radio buffer at the info level.
     * @param s The message to log
+99 −1
Original line number Diff line number Diff line
@@ -1137,6 +1137,70 @@ public class ImsManager implements FeatureUpdates {
        }
    }

    /**
     * @return true if the user's setting for Voice over Cross SIM is enabled and
     * false if it is not
     */
    public boolean isCrossSimCallingEnabledByUser() {
        int setting = mSubscriptionManagerProxy.getIntegerSubscriptionProperty(
                getSubId(), SubscriptionManager.CROSS_SIM_CALLING_ENABLED,
                SUB_PROPERTY_NOT_INITIALIZED);

        // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
        if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
            return false;
        } else {
            return setting == ProvisioningManager.PROVISIONING_VALUE_ENABLED;
        }
    }

    /**
     * @return true if Voice over Cross SIM is provisioned and enabled by user and platform.
     * false if any of them is not true
     */
    public boolean isCrossSimCallingEnabled() {
        boolean userEnabled = isCrossSimCallingEnabledByUser();
        boolean platformEnabled = isCrossSimEnabledByPlatform();
        boolean isProvisioned = isWfcProvisionedOnDevice();

        log("isCrossSimCallingEnabled: platformEnabled = " + platformEnabled
                + ", provisioned = " + isProvisioned
                + ", userEnabled = " + userEnabled);
        return userEnabled && platformEnabled && isProvisioned;
    }

    /**
     * Sets the user's setting for whether or not Voice over Cross SIM is enabled.
     */
    public void setCrossSimCallingEnabled(boolean enabled) {
        if (enabled && !isWfcProvisionedOnDevice()) {
            log("setCrossSimCallingEnabled: Not possible to enable WFC due to provisioning.");
            return;
        }
        int subId = getSubId();
        if (!isSubIdValid(subId)) {
            loge("setCrossSimCallingEnabled: "
                    + "invalid sub id, can not set Cross SIM setting in siminfo db; subId="
                    + subId);
            return;
        }
        mSubscriptionManagerProxy.setSubscriptionProperty(subId,
                SubscriptionManager.CROSS_SIM_CALLING_ENABLED, booleanToPropertyString(enabled));
        try {
            if (enabled) {
                CapabilityChangeRequest request = new CapabilityChangeRequest();
                updateCrossSimFeatureAndProvisionedValues(request);
                changeMmTelCapability(request);
                turnOnIms();
            } else {
                // Recalculate all caps to determine if IMS needs to be disabled.
                reevaluateCapabilities();
            }
        } catch (ImsException e) {
            loge("setCrossSimCallingEnabled(): ", e);
        }
    }

    /**
     * Non-persistently change WFC enabled setting and WFC mode for slot
     *
@@ -1469,6 +1533,19 @@ public class ImsManager implements FeatureUpdates {
                isGbaValid();
    }

    /**
     * Returns a platform configuration for Cross SIM which may override the user
     * setting per slot. Note: Cross SIM presumes that VoLTE is enabled (these are
     * configuration settings which must be done correctly).
     */
    public boolean isCrossSimEnabledByPlatform() {
        if (isWfcEnabledByPlatform()) {
            return getBooleanCarrierConfig(
                    CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL);
        }
        return false;
    }

    public boolean isSuppServicesOverUtEnabledByPlatform() {
        TelephonyManager manager = (TelephonyManager) mContext.getSystemService(
                Context.TELEPHONY_SERVICE);
@@ -1596,6 +1673,7 @@ public class ImsManager implements FeatureUpdates {
        boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
        updateVoiceCellFeatureValue(request, isNonTty);
        updateVoiceWifiFeatureAndProvisionedValues(request);
        updateCrossSimFeatureAndProvisionedValues(request);
        updateVideoCallFeatureValue(request, isNonTty);
        updateCallComposerFeatureValue(request);
        // Only turn on IMS for RTT if there's an active subscription present. If not, the
@@ -1775,6 +1853,21 @@ public class ImsManager implements FeatureUpdates {
        setWfcRoamingSettingInternal(roaming);
    }

    /**
     * Update Cross SIM config
     */
    private void updateCrossSimFeatureAndProvisionedValues(CapabilityChangeRequest request) {
        if (isCrossSimCallingEnabled()) {
            request.addCapabilitiesToEnableForTech(
                    MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
                    ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM);
        } else {
            request.addCapabilitiesToDisableForTech(
                    MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
                    ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM);
        }
    }


    private void updateUtFeatureValue(CapabilityChangeRequest request) {
        boolean isCarrierSupported = isSuppServicesOverUtEnabledByPlatform();
@@ -2525,8 +2618,10 @@ public class ImsManager implements FeatureUpdates {
        CapabilityChangeRequest request = new CapabilityChangeRequest();
        updateVoiceCellFeatureValue(request, isNonTtyOrTtyOnVolteEnabled);
        updateVideoCallFeatureValue(request, isNonTtyOrTtyOnVolteEnabled);
        if (isImsNeeded(request)) {
        // update MMTEL caps for the new configuration.
        changeMmTelCapability(request);
        if (isImsNeeded(request)) {
            // Only turn on IMS if voice/video is enabled now in the new configuration.
            turnOnIms();
        }
    }
@@ -3219,6 +3314,9 @@ public class ImsManager implements FeatureUpdates {

        pw.println("  isVtProvisionedOnDevice = " + isVtProvisionedOnDevice());
        pw.println("  isWfcProvisionedOnDevice = " + isWfcProvisionedOnDevice());

        pw.println("  isCrossSimEnabledByPlatform = " + isCrossSimEnabledByPlatform());
        pw.println("  isCrossSimCallingEnabledByUser = " + isCrossSimCallingEnabledByUser());
        pw.println("  isImsOverNrEnabledByPlatform = " + isImsOverNrEnabledByPlatform());
        pw.flush();
    }
+30 −4
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.telephony.ims.RcsUceAdapter.StackPublishTriggerType;
import android.telephony.ims.aidl.IOptionsRequestCallback;
import android.telephony.ims.aidl.IRcsUceControllerCallback;
import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
import android.util.IndentingPrintWriter;
import android.util.LocalLog;
import android.util.Log;

@@ -48,13 +49,14 @@ import com.android.ims.rcs.uce.presence.subscribe.SubscribeControllerImpl;
import com.android.ims.rcs.uce.request.UceRequestManager;
import com.android.ims.rcs.uce.util.UceUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.os.SomeArgs;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

@@ -96,8 +98,9 @@ public class UceController {
         * Refresh the device state. It is called when receive the UCE request response.
         * @param sipCode The SIP code of the request response.
         * @param reason The reason from the network response.
         * @param type The type of the request
         */
        void refreshDeviceState(int sipCode, String reason);
        void refreshDeviceState(int sipCode, String reason, @RequestType int type);

        /**
         * Reset the device state when then device disallowed state is expired.
@@ -255,6 +258,29 @@ public class UceController {
        }
    }

    /**
     * The request type is PUBLISH.
     */
    public static final int REQUEST_TYPE_PUBLISH = 1;

    /**
     * The request type is CAPABILITY.
     */
    public static final int REQUEST_TYPE_CAPABILITY = 2;

    @IntDef(value = {
            REQUEST_TYPE_PUBLISH,
            REQUEST_TYPE_CAPABILITY,
    }, prefix="REQUEST_TYPE_")
    @Retention(RetentionPolicy.SOURCE)
    public @interface RequestType {}

    public static final Map<Integer, String> REQUEST_TYPE_DESCRIPTION = new HashMap<>();
    static {
        REQUEST_TYPE_DESCRIPTION.put(REQUEST_TYPE_PUBLISH, "REQUEST_TYPE_PUBLISH");
        REQUEST_TYPE_DESCRIPTION.put(REQUEST_TYPE_CAPABILITY, "REQUEST_TYPE_CAPABILITY");
    }

    /** The RCS state is disconnected */
    private static final int RCS_STATE_DISCONNECTED = 0;

@@ -465,8 +491,8 @@ public class UceController {
        }

        @Override
        public void refreshDeviceState(int sipCode, String reason) {
            mDeviceState.refreshDeviceState(sipCode, reason);
        public void refreshDeviceState(int sipCode, String reason, @RequestType int type) {
            mDeviceState.refreshDeviceState(sipCode, reason, type);
        }

        @Override
+49 −10
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context;
import android.telephony.ims.RcsUceAdapter.ErrorCode;
import android.util.Log;

import com.android.ims.rcs.uce.UceController.RequestType;
import com.android.ims.rcs.uce.UceController.UceControllerCallback;
import com.android.ims.rcs.uce.util.NetworkSipCode;
import com.android.ims.rcs.uce.util.UceUtils;
@@ -29,6 +30,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
@@ -49,20 +52,35 @@ public class UceDeviceState {
     */
    private static final int DEVICE_STATE_FORBIDDEN = 1;

    /**
     * The device will be in the PROVISION error state when the PUBLISH request fails and the
     * SIP code is 404 NOT FOUND.
     */
    private static final int DEVICE_STATE_PROVISION_ERROR = 2;

    /**
     * When the network response SIP code is 489 and the carrier config also indicates that needs
     * to handle the SIP code 489, the device will be in the BAD EVENT state.
     */
    private static final int DEVICE_STATE_BAD_EVENT = 2;
    private static final int DEVICE_STATE_BAD_EVENT = 3;

    @IntDef(value = {
            DEVICE_STATE_OK,
            DEVICE_STATE_FORBIDDEN,
            DEVICE_STATE_PROVISION_ERROR,
            DEVICE_STATE_BAD_EVENT,
    }, prefix="DEVICE_STATE_")
    @Retention(RetentionPolicy.SOURCE)
    public @interface DeviceStateType {}

    private static final Map<Integer, String> DEVICE_STATE_DESCRIPTION = new HashMap<>();
    static {
        DEVICE_STATE_DESCRIPTION.put(DEVICE_STATE_OK, "DEVICE_STATE_OK");
        DEVICE_STATE_DESCRIPTION.put(DEVICE_STATE_FORBIDDEN, "DEVICE_STATE_FORBIDDEN");
        DEVICE_STATE_DESCRIPTION.put(DEVICE_STATE_PROVISION_ERROR, "DEVICE_STATE_PROVISION_ERROR");
        DEVICE_STATE_DESCRIPTION.put(DEVICE_STATE_BAD_EVENT, "DEVICE_STATE_BAD_EVENT");
    }

    /**
     * The result of the current device state.
     */
@@ -86,6 +104,7 @@ public class UceDeviceState {
        public boolean isRequestForbidden() {
            switch(mDeviceState) {
                case DEVICE_STATE_FORBIDDEN:
                case DEVICE_STATE_PROVISION_ERROR:
                case DEVICE_STATE_BAD_EVENT:
                    return true;
                default:
@@ -133,7 +152,7 @@ public class UceDeviceState {
        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder();
            builder.append("DeviceState=").append(getDeviceState())
            builder.append("DeviceState=").append(DEVICE_STATE_DESCRIPTION.get(getDeviceState()))
                    .append(", ErrorCode=").append(getErrorCode())
                    .append(", RetryTime=").append(getRequestRetryTime())
                    .append(", retryAfterMillis=").append(getRequestRetryAfterMillis())
@@ -203,9 +222,12 @@ public class UceDeviceState {
     * Update the device state to determine whether the device is allowed to send requests or not.
     *  @param sipCode The SIP CODE of the request result.
     *  @param reason The reason from the network response.
     *  @param requestType The type of the request.
     */
    public synchronized void refreshDeviceState(int sipCode, String reason) {
        logd("refreshDeviceState: sipCode=" + sipCode + ", reason=" + reason);
    public synchronized void refreshDeviceState(int sipCode, String reason,
            @RequestType int requestType) {
        logd("refreshDeviceState: sipCode=" + sipCode + ", reason=" + reason +
                ", requestResponseType=" + UceController.REQUEST_TYPE_DESCRIPTION.get(requestType));

        // Get the current device status before updating the state.
        DeviceStateResult previousState = getCurrentState();
@@ -213,18 +235,35 @@ public class UceDeviceState {
        // Update the device state based on the given sip code.
        switch (sipCode) {
            case NetworkSipCode.SIP_CODE_FORBIDDEN:   // sip 403
                if (requestType == UceController.REQUEST_TYPE_PUBLISH) {
                    // Provisioning error for publish request.
                    setDeviceState(DEVICE_STATE_PROVISION_ERROR);
                } else {
                    setDeviceState(DEVICE_STATE_FORBIDDEN);
                updateErrorCode(sipCode, reason);
                }
                updateErrorCode(sipCode, reason, requestType);
                // There is no request retry time for SIP code 403
                removeRequestRetryTime();
                // No timer to exit the forbidden state.
                removeExitStateTimer();
                break;

            case NetworkSipCode.SIP_CODE_NOT_FOUND:  // sip 404
                // DeviceState only handles 404 NOT FOUND error for PUBLISH request.
                if (requestType == UceController.REQUEST_TYPE_PUBLISH) {
                    setDeviceState(DEVICE_STATE_PROVISION_ERROR);
                    updateErrorCode(sipCode, reason, requestType);
                    // There is no request retry time for SIP code 404
                    removeRequestRetryTime();
                    // No timer to exit this state.
                    removeExitStateTimer();
                }
                break;

            case NetworkSipCode.SIP_CODE_BAD_EVENT:   // sip 489
                if (UceUtils.isRequestForbiddenBySip489(mContext, mSubId)) {
                    setDeviceState(DEVICE_STATE_BAD_EVENT);
                    updateErrorCode(sipCode, reason);
                    updateErrorCode(sipCode, reason, requestType);
                    // Setup the request retry time.
                    setupRequestRetryTime();
                    // Setup the timer to exit the BAD EVENT state.
@@ -251,7 +290,7 @@ public class UceDeviceState {
            saveDeviceStateToPreference(currentState);
        }

        logd("refreshDeviceState: previous=" + previousState + ", current=" + currentState);
        logd("refreshDeviceState: previous: " + previousState + ", current: " + currentState);
    }

    /**
@@ -285,9 +324,9 @@ public class UceDeviceState {
        }
    }

    private void updateErrorCode(int sipCode, String reason) {
    private void updateErrorCode(int sipCode, String reason, @RequestType int requestType) {
        Optional<Integer> newErrorCode = Optional.of(NetworkSipCode.getCapabilityErrorFromSipCode(
                sipCode, reason));
                    sipCode, reason, requestType));
        if (!mErrorCode.equals(newErrorCode)) {
            mErrorCode = newErrorCode;
        }
+2 −5
Original line number Diff line number Diff line
@@ -19,8 +19,6 @@ package com.android.ims.rcs.uce.eab;
import static android.telephony.ims.RcsContactUceCapability.CAPABILITY_MECHANISM_OPTIONS;
import static android.telephony.ims.RcsContactUceCapability.CAPABILITY_MECHANISM_PRESENCE;

import static com.android.ims.rcs.uce.eab.EabControllerImpl.getCapabilityCacheExpiration;

import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -31,7 +29,6 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
@@ -291,7 +288,7 @@ public final class EabBulkCapabilityUpdater {
                Log.d(TAG, "Can't find min timestamp in eab provider");
                return;
            }
            expiredTimestamp += getCapabilityCacheExpiration(mSubId);
            expiredTimestamp += mEabControllerImpl.getCapabilityCacheExpiration(mSubId);
            Log.d(TAG, "set time alert at " + expiredTimestamp);
            cancelTimeAlert(mContext);
            setTimeAlert(mContext, expiredTimestamp);
@@ -398,7 +395,7 @@ public final class EabBulkCapabilityUpdater {
    private List<Uri> getExpiredContactList() {
        List<Uri> refreshList = new ArrayList<>();
        long expiredTime = (System.currentTimeMillis() / 1000)
                + getCapabilityCacheExpiration(mSubId);
                + mEabControllerImpl.getCapabilityCacheExpiration(mSubId);
        String selection = "("
                + EabProvider.EabCommonColumns.MECHANISM + "=" + CAPABILITY_MECHANISM_PRESENCE
                + " AND " + EabProvider.PresenceTupleColumns.REQUEST_TIMESTAMP + "<"
Loading