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

Commit b2f1e2cc authored by James.cf Lin's avatar James.cf Lin
Browse files

When receiving the empty pidf xml data, treat the contacts as a non-RCS user

Bug: 191117473
Test: atest -c CtsTelephonyTestCases:android.telephony.ims.cts.RcsUceAdapterTest
Change-Id: Ifaeaadfb677b5a93579f09fffc489ba902f597a1
parent 1a030c4a
Loading
Loading
Loading
Loading
+33 −19
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.RcsUceAdapter.ErrorCode;
import android.telephony.ims.stub.RcsCapabilityExchangeImplBase;
import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.CommandCode;
import android.text.TextUtils;
import android.util.Log;

import com.android.ims.rcs.uce.UceController;
@@ -82,7 +83,7 @@ public class CapabilityRequestResponse {
    private Set<String> mRemoteCaps;

    // The collection to record whether the request contacts have received the capabilities updated.
    private Map<String, Boolean> mContactCapsReceived;
    private Map<Uri, Boolean> mContactCapsReceived;

    public CapabilityRequestResponse() {
        mRequestInternalError = Optional.empty();
@@ -104,18 +105,23 @@ public class CapabilityRequestResponse {
     * Set the request contacts which is expected to receive the capabilities updated.
     */
    public synchronized void setRequestContacts(List<Uri> contactUris) {
        // Convert the given contact uris to the contact numbers.
        List<String> numbers = contactUris.stream()
                .map(UceUtils::getContactNumber)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // Initialize the default value to FALSE. All the numbers have not received the
        // capabilities updated.
        numbers.stream().forEach(contact -> mContactCapsReceived.put(contact, Boolean.FALSE));
        contactUris.forEach(contact -> mContactCapsReceived.put(contact, Boolean.FALSE));
        Log.d(LOG_TAG, "setRequestContacts: size=" + mContactCapsReceived.size());
    }

    /**
     * Get the contacts that have not received the capabilities updated yet.
     */
    public synchronized List<Uri> getNotReceiveCapabilityUpdatedContact() {
        return mContactCapsReceived.entrySet()
                .stream()
                .filter(entry -> Objects.equals(entry.getValue(), Boolean.FALSE))
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }

    /**
     * Set the request contacts which is expected to receive the capabilities updated.
     */
@@ -251,8 +257,9 @@ public class CapabilityRequestResponse {
            if (updatedUri == null) continue;
            String updatedUriStr = updatedUri.toString();

            for (Map.Entry<String, Boolean> contactCapEntry : mContactCapsReceived.entrySet()) {
                if (updatedUriStr.contains(contactCapEntry.getKey())) {
            for (Map.Entry<Uri, Boolean> contactCapEntry : mContactCapsReceived.entrySet()) {
                String number = UceUtils.getContactNumber(contactCapEntry.getKey());
                if (!TextUtils.isEmpty(number) && updatedUriStr.contains(number)) {
                    // Set the flag that this contact has received the capability updated.
                    contactCapEntry.setValue(true);
                }
@@ -380,18 +387,25 @@ public class CapabilityRequestResponse {

    /**
     * Check the contacts of the request is not found.
     * @return true if the sip code of the network response is NOT_FOUND(404) or
     * DOES_NOT_EXIST_ANYWHERE(604)
     * @return true if the sip code of the network response is one of NOT_FOUND(404),
     * SIP_CODE_METHOD_NOT_ALLOWED(405) or DOES_NOT_EXIST_ANYWHERE(604)
     */
    public synchronized boolean isNotFound() {
        final int notFound = NetworkSipCode.SIP_CODE_NOT_FOUND;
        final int notExistAnywhere = NetworkSipCode.SIP_CODE_DOES_NOT_EXIST_ANYWHERE;
        Optional<Integer> reasonHeaderCause = getReasonHeaderCause();
        Optional<Integer> respSipCode = getNetworkRespSipCode();
        if (reasonHeaderCause.filter(c -> c == notFound || c == notExistAnywhere).isPresent() ||
                respSipCode.filter(c -> c == notFound || c == notExistAnywhere).isPresent()) {
        Optional<Integer> respSipCode = Optional.empty();
        if (getReasonHeaderCause().isPresent()) {
            respSipCode = getReasonHeaderCause();
        } else if (getNetworkRespSipCode().isPresent()) {
            respSipCode = getNetworkRespSipCode();
        }

        if (respSipCode.isPresent()) {
            int sipCode = respSipCode.get();
            if (sipCode == NetworkSipCode.SIP_CODE_NOT_FOUND ||
            sipCode == NetworkSipCode.SIP_CODE_METHOD_NOT_ALLOWED ||
            sipCode == NetworkSipCode.SIP_CODE_DOES_NOT_EXIST_ANYWHERE) {
                return true;
            }
        }
        return false;
    }

+13 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.telephony.ims.aidl.ISubscribeResponseCallback;
import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.CommandCode;

import com.android.ims.rcs.uce.presence.pidfparser.PidfParser;
import com.android.ims.rcs.uce.presence.pidfparser.PidfParserUtils;
import com.android.ims.rcs.uce.presence.subscribe.SubscribeController;
import com.android.ims.rcs.uce.request.UceRequestManager.RequestManagerCallback;
import com.android.internal.annotations.VisibleForTesting;
@@ -194,6 +195,18 @@ public class SubscribeRequest extends CapabilityRequest {
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // When the given PIDF xml is empty, set the contacts who have not received the
        // capabilities updated as non-RCS user.
        if (capabilityList.isEmpty()) {
            logd("onCapabilitiesUpdate: The capabilities list is empty, Set to non-RCS user.");
            List<Uri> notReceiveCapUpdatedContactList =
                    mRequestResponse.getNotReceiveCapabilityUpdatedContact();
            capabilityList = notReceiveCapUpdatedContactList.stream()
                    .map(PidfParserUtils::getNotFoundContactCapabilities)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
        }

        logd("onCapabilitiesUpdate: PIDF size=" + pidfXml.size()
                + ", contact capability size=" + capabilityList.size());

+27 −9
Original line number Diff line number Diff line
@@ -113,6 +113,11 @@ public class SubscribeRequestCoordinator extends UceRequestCoordinator {
        }
    };

    // The RequestResult creator of the network response is not 200 OK, however, we can to treat
    // it as a successful result and finish the request
    private static final RequestResultCreator sNetworkRespSuccessfulCreator = (taskId, response,
            requestMgrCallback) -> RequestResult.createSuccessResult(taskId);

    // The RequestResult creator of the request terminated.
    private static final RequestResultCreator sTerminatedCreator = (taskId, response,
            requestMgrCallback) -> {
@@ -266,12 +271,9 @@ public class SubscribeRequestCoordinator extends UceRequestCoordinator {
        // request. Check the forbidden state and finish this request. Otherwise, keep waiting for
        // the subsequent callback of this request.
        if (!response.isNetworkResponseOK()) {
            Long taskId = request.getTaskId();
            RequestResult requestResult = sNetworkRespErrorCreator.createRequestResult(taskId,
                    response, mRequestManagerCallback);

            // handle forbidden and not found case.
            handleNetworkResponseFailed(request, requestResult);
            // Handle the network response not OK cases and get the request result to finish this
            // request.
            RequestResult requestResult = handleNetworkResponseFailed(request);

            // Trigger capabilities updated callback if there is any.
            List<RcsContactUceCapability> updatedCapList = response.getUpdatedContactCapability();
@@ -285,20 +287,36 @@ public class SubscribeRequestCoordinator extends UceRequestCoordinator {
            request.onFinish();

            // Remove this request from the activated collection and notify RequestManager.
            moveRequestToFinishedCollection(taskId, requestResult);
            moveRequestToFinishedCollection(request.getTaskId(), requestResult);
        }
    }

    private void handleNetworkResponseFailed(SubscribeRequest request, RequestResult result) {
        CapabilityRequestResponse response = request.getRequestResponse();
    private RequestResult handleNetworkResponseFailed(SubscribeRequest request) {
        final long taskId = request.getTaskId();
        final CapabilityRequestResponse response = request.getRequestResponse();
        RequestResult requestResult = null;

        if (response.isNotFound()) {
            // In the network response with the not found case, we won't receive the capabilities
            // updated callback from the ImsService afterward. Therefore, we create the capabilities
            // with the result REQUEST_RESULT_NOT_FOUND by ourself and will trigger the
            // capabilities received callback to the clients later.
            List<Uri> uriList = request.getContactUri();
            List<RcsContactUceCapability> capabilityList = uriList.stream().map(uri ->
                    PidfParserUtils.getNotFoundContactCapabilities(uri))
                    .collect(Collectors.toList());
            response.addUpdatedCapabilities(capabilityList);

            // We treat the NOT FOUND is a successful result.
            requestResult = sNetworkRespSuccessfulCreator.createRequestResult(taskId, response,
                    mRequestManagerCallback);
        }

        if (requestResult == null) {
            requestResult = sNetworkRespErrorCreator.createRequestResult(taskId, response,
                    mRequestManagerCallback);
        }
        return requestResult;
    }

    /**
+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ public class NetworkSipCode {
    public static final int SIP_CODE_BAD_REQUEST = 400;
    public static final int SIP_CODE_FORBIDDEN = 403;
    public static final int SIP_CODE_NOT_FOUND = 404;
    public static final int SIP_CODE_METHOD_NOT_ALLOWED = 405;
    public static final int SIP_CODE_REQUEST_TIMEOUT = 408;
    public static final int SIP_CODE_INTERVAL_TOO_BRIEF = 423;
    public static final int SIP_CODE_TEMPORARILY_UNAVAILABLE = 480;