From b2f1e2cc3b5ba177003d5b4fcf495f04a25bec77 Mon Sep 17 00:00:00 2001 From: "James.cf Lin" Date: Wed, 16 Jun 2021 22:26:41 +0800 Subject: 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 --- .../rcs/uce/request/CapabilityRequestResponse.java | 52 ++++++++++++++-------- .../ims/rcs/uce/request/SubscribeRequest.java | 13 ++++++ .../uce/request/SubscribeRequestCoordinator.java | 36 +++++++++++---- .../android/ims/rcs/uce/util/NetworkSipCode.java | 1 + 4 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/java/com/android/ims/rcs/uce/request/CapabilityRequestResponse.java b/src/java/com/android/ims/rcs/uce/request/CapabilityRequestResponse.java index 1ac46a7a..97371b8b 100644 --- a/src/java/com/android/ims/rcs/uce/request/CapabilityRequestResponse.java +++ b/src/java/com/android/ims/rcs/uce/request/CapabilityRequestResponse.java @@ -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 mRemoteCaps; // The collection to record whether the request contacts have received the capabilities updated. - private Map mContactCapsReceived; + private Map 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 contactUris) { - // Convert the given contact uris to the contact numbers. - List 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 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 contactCapEntry : mContactCapsReceived.entrySet()) { - if (updatedUriStr.contains(contactCapEntry.getKey())) { + for (Map.Entry 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,17 +387,24 @@ 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 reasonHeaderCause = getReasonHeaderCause(); - Optional respSipCode = getNetworkRespSipCode(); - if (reasonHeaderCause.filter(c -> c == notFound || c == notExistAnywhere).isPresent() || - respSipCode.filter(c -> c == notFound || c == notExistAnywhere).isPresent()) { - return true; + Optional 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; } diff --git a/src/java/com/android/ims/rcs/uce/request/SubscribeRequest.java b/src/java/com/android/ims/rcs/uce/request/SubscribeRequest.java index eb368392..2b5e91a9 100644 --- a/src/java/com/android/ims/rcs/uce/request/SubscribeRequest.java +++ b/src/java/com/android/ims/rcs/uce/request/SubscribeRequest.java @@ -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 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()); diff --git a/src/java/com/android/ims/rcs/uce/request/SubscribeRequestCoordinator.java b/src/java/com/android/ims/rcs/uce/request/SubscribeRequestCoordinator.java index 54aa5cc9..ee6bd356 100644 --- a/src/java/com/android/ims/rcs/uce/request/SubscribeRequestCoordinator.java +++ b/src/java/com/android/ims/rcs/uce/request/SubscribeRequestCoordinator.java @@ -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 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 uriList = request.getContactUri(); List 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; } /** diff --git a/src/java/com/android/ims/rcs/uce/util/NetworkSipCode.java b/src/java/com/android/ims/rcs/uce/util/NetworkSipCode.java index 3789903f..a1e35d76 100644 --- a/src/java/com/android/ims/rcs/uce/util/NetworkSipCode.java +++ b/src/java/com/android/ims/rcs/uce/util/NetworkSipCode.java @@ -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; -- cgit v1.2.3