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

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

Check whether all the request capabilities have been received or not when the...

Check whether all the request capabilities have been received or not when the UCE subscribe request has received the onTerminated with the reason "timeout"

Bug: 188469053
Test: atest -c CtsTelephonyTestCases:android.telephony.ims.cts.RcsUceAdapterTest
Merged-In: I677d5b5eb7bb3d0114dc822023c9743467854933
Change-Id: I677d5b5eb7bb3d0114dc822023c9743467854933
parent 01f5cd10
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ public abstract class CapabilityRequest implements UceRequest {
    @Override
    public void setContactUri(List<Uri> uris) {
        mUriList.addAll(uris);
        mRequestResponse.setRequestContacts(uris);
    }

    public List<Uri> getContactUri() {
+39 −0
Original line number Diff line number Diff line
@@ -16,20 +16,25 @@

package com.android.ims.rcs.uce.request;

import android.net.Uri;
import android.telephony.ims.RcsContactTerminatedReason;
import android.telephony.ims.RcsContactUceCapability;
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.util.Log;

import com.android.ims.rcs.uce.presence.pidfparser.PidfParserUtils;
import com.android.ims.rcs.uce.util.NetworkSipCode;
import com.android.ims.rcs.uce.util.UceUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@@ -39,6 +44,9 @@ import java.util.stream.Collectors;
 * The container of the result of the capabilities request.
 */
public class CapabilityRequestResponse {

    private static final String LOG_TAG = UceUtils.getLogPrefix() + "CapabilityRequestResp";

    // The error code when the request encounters internal errors.
    private @ErrorCode Optional<Integer> mRequestInternalError;

@@ -72,6 +80,9 @@ public class CapabilityRequestResponse {
    // The list of the remote contact's capability.
    private Set<String> mRemoteCaps;

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

    public CapabilityRequestResponse() {
        mRequestInternalError = Optional.empty();
        mCommandError = Optional.empty();
@@ -85,6 +96,22 @@ public class CapabilityRequestResponse {
        mCachedCapabilityList = new ArrayList<>();
        mUpdatedCapabilityList = new ArrayList<>();
        mRemoteCaps = new HashSet<>();
        mContactCapsReceived = new HashMap<>();
    }

    /**
     * Set the request contacts which is expected to receive the capabilities updated.
     */
    public synchronized void setRequestContacts(List<Uri> contactUris) {
        contactUris.stream().forEach(contact -> mContactCapsReceived.put(contact, Boolean.FALSE));
        Log.d(LOG_TAG, "setRequestContacts: size=" + mContactCapsReceived.size());
    }

    /**
     * Set the request contacts which is expected to receive the capabilities updated.
     */
    public synchronized boolean haveAllRequestCapsUpdatedBeenReceived() {
        return !(mContactCapsReceived.containsValue(Boolean.FALSE));
    }

    /**
@@ -201,6 +228,10 @@ public class CapabilityRequestResponse {
     */
    public synchronized void addCachedCapabilities(List<RcsContactUceCapability> capabilityList) {
        mCachedCapabilityList.addAll(capabilityList);

        // Record which contact has received the capabilities updated.
        capabilityList.stream().forEach(cap ->
            mContactCapsReceived.computeIfPresent(cap.getContactUri(), (k, v) -> Boolean.TRUE));
    }

    /**
@@ -222,6 +253,10 @@ public class CapabilityRequestResponse {
     */
    public synchronized void addUpdatedCapabilities(List<RcsContactUceCapability> capabilityList) {
        mUpdatedCapabilityList.addAll(capabilityList);

        // Record which contact has received the capabilities updated.
        capabilityList.stream().forEach(cap ->
                mContactCapsReceived.computeIfPresent(cap.getContactUri(), (k, v) -> Boolean.TRUE));
    }

    /**
@@ -251,6 +286,10 @@ public class CapabilityRequestResponse {

        // Save the terminated resource.
        mTerminatedResource.addAll(capabilityList);

        // Record which contact has received the capabilities updated.
        capabilityList.stream().forEach(cap ->
                mContactCapsReceived.computeIfPresent(cap.getContactUri(), (k, v) -> Boolean.TRUE));
    }

    /*
+2 −1
Original line number Diff line number Diff line
@@ -118,7 +118,8 @@ public class SubscribeRequestCoordinator extends UceRequestCoordinator {
            requestMgrCallback) -> {
        // Check the given terminated reason to determine whether clients should retry or not.
        TerminatedResult terminatedResult = SubscriptionTerminatedHelper.getAnalysisResult(
                response.getTerminatedReason(), response.getRetryAfterMillis());
                response.getTerminatedReason(), response.getRetryAfterMillis(),
                response.haveAllRequestCapsUpdatedBeenReceived());
        if (terminatedResult.getErrorCode().isPresent()) {
            // If the terminated error code is present, it means that the request is failed.
            int errorCode = terminatedResult.getErrorCode().get();
+27 −10
Original line number Diff line number Diff line
@@ -83,8 +83,10 @@ public class SubscriptionTerminatedHelper {
     * @param reason The reason why the subscribe request is terminated. The reason is given by the
     * network and it could be empty.
     * @param retryAfterMillis How long should clients wait before retrying.
     * @param allCapsHaveReceived Whether all the request contact capabilities have been received.
     */
    public static TerminatedResult getAnalysisResult(String reason, long retryAfterMillis) {
    public static TerminatedResult getAnalysisResult(String reason, long retryAfterMillis,
            boolean allCapsHaveReceived) {
        TerminatedResult result = null;
        if (TextUtils.isEmpty(reason)) {
            /*
@@ -113,14 +115,29 @@ public class SubscriptionTerminatedHelper {
             * due to chang in authorization policy. Clients should NOT retry.
             */
            result = new TerminatedResult(Optional.of(RcsUceAdapter.ERROR_NOT_AUTHORIZED), 0L);
        } else if (REASON_TIMEOUT.equalsIgnoreCase(reason) && retryAfterMillis > 0L) {
        } else if (REASON_TIMEOUT.equalsIgnoreCase(reason)) {
            if (retryAfterMillis > 0L) {
                /*
             * The subscription has been terminated because it was not refreshed before it expired.
             * The request completes successfully when the retryAfter is not set. Otherwise, the
             * request should retry if the retryAfter is set.
                 * When the parameter "retryAfterMillis" is greater than zero, it means that the
                 * ImsService requires clients should retry later.
                 */
                long retry = getRequestRetryAfterMillis(retryAfterMillis);
            result = new TerminatedResult(Optional.of(RcsUceAdapter.ERROR_REQUEST_TIMEOUT), retry);
                result = new TerminatedResult(Optional.of(RcsUceAdapter.ERROR_REQUEST_TIMEOUT),
                        retry);
            } else if (!allCapsHaveReceived) {
                /*
                 * The ImsService does not require to retry when the parameter "retryAfterMillis"
                 * is zero. However, the request is still failed because it has not received all
                 * the capabilities updated from the network.
                 */
                result = new TerminatedResult(Optional.of(RcsUceAdapter.ERROR_REQUEST_TIMEOUT), 0L);
            } else {
                /*
                 * The subscribe request is successfully when the parameter retryAfter is zero and
                 * all the request capabilities have been received.
                 */
                result = new TerminatedResult(Optional.empty(), 0L);
            }
        } else if (REASON_GIVEUP.equalsIgnoreCase(reason)) {
            /*
             * The subscription has been terminated because the notifier could no obtain
@@ -149,7 +166,7 @@ public class SubscriptionTerminatedHelper {
        }

        Log.d(LOG_TAG, "getAnalysisResult: reason=" + reason + ", retry=" + retryAfterMillis +
                ", " + result);
                ", allCapsHaveReceived=" + allCapsHaveReceived + ", " + result);
        return result;
    }