1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ims.rcs.uce.presence.pidfparser; 18 19 import android.net.Uri; 20 import android.telephony.ims.RcsContactPresenceTuple; 21 import android.telephony.ims.RcsContactPresenceTuple.BasicStatus; 22 import android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities; 23 import android.telephony.ims.RcsContactUceCapability; 24 import android.text.TextUtils; 25 26 import com.android.ims.rcs.uce.presence.pidfparser.capabilities.Audio; 27 import com.android.ims.rcs.uce.presence.pidfparser.capabilities.Duplex; 28 import com.android.ims.rcs.uce.presence.pidfparser.capabilities.ServiceCaps; 29 import com.android.ims.rcs.uce.presence.pidfparser.capabilities.Video; 30 import com.android.ims.rcs.uce.presence.pidfparser.omapres.Description; 31 import com.android.ims.rcs.uce.presence.pidfparser.omapres.ServiceDescription; 32 import com.android.ims.rcs.uce.presence.pidfparser.omapres.ServiceId; 33 import com.android.ims.rcs.uce.presence.pidfparser.omapres.Version; 34 import com.android.ims.rcs.uce.presence.pidfparser.pidf.Basic; 35 import com.android.ims.rcs.uce.presence.pidfparser.pidf.Contact; 36 import com.android.ims.rcs.uce.presence.pidfparser.pidf.Presence; 37 import com.android.ims.rcs.uce.presence.pidfparser.pidf.Status; 38 import com.android.ims.rcs.uce.presence.pidfparser.pidf.Timestamp; 39 import com.android.ims.rcs.uce.presence.pidfparser.pidf.Tuple; 40 41 import java.util.Arrays; 42 import java.util.List; 43 44 /** 45 * The utils to help the PIDF parsing process. 46 */ 47 public class PidfParserUtils { 48 49 /* 50 * The resource terminated reason with NOT FOUND 51 */ 52 private static String[] REQUEST_RESULT_REASON_NOT_FOUND = { "noresource", "rejected" }; 53 54 /** 55 * Convert the given class RcsContactUceCapability to the class Presence. 56 */ getPresence(RcsContactUceCapability capabilities)57 static Presence getPresence(RcsContactUceCapability capabilities) { 58 // Create "presence" element which is the root element of the pidf 59 Presence presence = new Presence(capabilities.getContactUri()); 60 61 List<RcsContactPresenceTuple> tupleList = capabilities.getCapabilityTuples(); 62 if (tupleList == null || tupleList.isEmpty()) { 63 return presence; 64 } 65 66 for (RcsContactPresenceTuple presenceTuple : tupleList) { 67 Tuple tupleElement = getTupleElement(presenceTuple); 68 if (tupleElement != null) { 69 presence.addTuple(tupleElement); 70 } 71 } 72 73 return presence; 74 } 75 76 /** 77 * Convert the class from RcsContactPresenceTuple to the class Tuple 78 */ getTupleElement(RcsContactPresenceTuple presenceTuple)79 private static Tuple getTupleElement(RcsContactPresenceTuple presenceTuple) { 80 if (presenceTuple == null) { 81 return null; 82 } 83 Tuple tupleElement = new Tuple(); 84 85 // status element 86 handleTupleStatusElement(tupleElement, presenceTuple.getStatus()); 87 88 // service description element 89 handleTupleServiceDescriptionElement(tupleElement, presenceTuple.getServiceId(), 90 presenceTuple.getServiceVersion(), presenceTuple.getServiceDescription()); 91 92 // service capabilities element 93 handleServiceCapsElement(tupleElement, presenceTuple.getServiceCapabilities()); 94 95 // contact element 96 handleTupleContactElement(tupleElement, presenceTuple.getContactUri()); 97 98 return tupleElement; 99 } 100 handleTupleContactElement(Tuple tupleElement, Uri uri)101 private static void handleTupleContactElement(Tuple tupleElement, Uri uri) { 102 if (uri == null) { 103 return; 104 } 105 Contact contactElement = new Contact(); 106 contactElement.setContact(uri.toString()); 107 tupleElement.setContact(contactElement); 108 } 109 handleTupleStatusElement(Tuple tupleElement, @BasicStatus String status)110 private static void handleTupleStatusElement(Tuple tupleElement, @BasicStatus String status) { 111 if (TextUtils.isEmpty(status)) { 112 return; 113 } 114 Basic basicElement = new Basic(status); 115 Status statusElement = new Status(); 116 statusElement.setBasic(basicElement); 117 tupleElement.setStatus(statusElement); 118 } 119 handleTupleServiceDescriptionElement(Tuple tupleElement, String serviceId, String version, String description)120 private static void handleTupleServiceDescriptionElement(Tuple tupleElement, String serviceId, 121 String version, String description) { 122 ServiceId serviceIdElement = null; 123 Version versionElement = null; 124 Description descriptionElement = null; 125 126 // init serviceId element 127 if (!TextUtils.isEmpty(serviceId)) { 128 serviceIdElement = new ServiceId(serviceId); 129 } 130 131 // init version element 132 if (!TextUtils.isEmpty(version)) { 133 String[] versionAry = version.split("\\."); 134 if (versionAry != null && versionAry.length == 2) { 135 int majorVersion = Integer.parseInt(versionAry[0]); 136 int minorVersion = Integer.parseInt(versionAry[1]); 137 versionElement = new Version(majorVersion, minorVersion); 138 } 139 } 140 141 // init description element 142 if (!TextUtils.isEmpty(description)) { 143 descriptionElement = new Description(description); 144 } 145 146 // Add the Service Description element into the tuple 147 if (serviceIdElement != null && versionElement != null) { 148 ServiceDescription serviceDescription = new ServiceDescription(); 149 serviceDescription.setServiceId(serviceIdElement); 150 serviceDescription.setVersion(versionElement); 151 if (descriptionElement != null) { 152 serviceDescription.setDescription(descriptionElement); 153 } 154 tupleElement.setServiceDescription(serviceDescription); 155 } 156 } 157 handleServiceCapsElement(Tuple tupleElement, ServiceCapabilities serviceCaps)158 private static void handleServiceCapsElement(Tuple tupleElement, 159 ServiceCapabilities serviceCaps) { 160 if (serviceCaps == null) { 161 return; 162 } 163 164 ServiceCaps servCapsElement = new ServiceCaps(); 165 166 // Audio and Video element 167 Audio audioElement = new Audio(serviceCaps.isAudioCapable()); 168 Video videoElement = new Video(serviceCaps.isVideoCapable()); 169 servCapsElement.addElement(audioElement); 170 servCapsElement.addElement(videoElement); 171 172 // Duplex element 173 List<String> supportedDuplexModes = serviceCaps.getSupportedDuplexModes(); 174 List<String> UnsupportedDuplexModes = serviceCaps.getUnsupportedDuplexModes(); 175 if ((supportedDuplexModes != null && !supportedDuplexModes.isEmpty()) || 176 (UnsupportedDuplexModes != null && !UnsupportedDuplexModes.isEmpty())) { 177 Duplex duplex = new Duplex(); 178 if (!supportedDuplexModes.isEmpty()) { 179 duplex.addSupportedType(supportedDuplexModes.get(0)); 180 } 181 if (!UnsupportedDuplexModes.isEmpty()) { 182 duplex.addNotSupportedType(UnsupportedDuplexModes.get(0)); 183 } 184 servCapsElement.addElement(duplex); 185 } 186 187 tupleElement.setServiceCaps(servCapsElement); 188 } 189 190 /** 191 * Get the status from the given tuple. 192 */ getTupleStatus(Tuple tuple)193 public static String getTupleStatus(Tuple tuple) { 194 if (tuple == null) { 195 return null; 196 } 197 Status status = tuple.getStatus(); 198 if (status != null) { 199 Basic basic = status.getBasic(); 200 if (basic != null) { 201 return basic.getValue(); 202 } 203 } 204 return null; 205 } 206 207 /** 208 * Get the service Id from the given tuple. 209 */ getTupleServiceId(Tuple tuple)210 public static String getTupleServiceId(Tuple tuple) { 211 if (tuple == null) { 212 return null; 213 } 214 ServiceDescription servDescription = tuple.getServiceDescription(); 215 if (servDescription != null) { 216 ServiceId serviceId = servDescription.getServiceId(); 217 if (serviceId != null) { 218 return serviceId.getValue(); 219 } 220 } 221 return null; 222 } 223 224 /** 225 * Get the service version from the given tuple. 226 */ getTupleServiceVersion(Tuple tuple)227 public static String getTupleServiceVersion(Tuple tuple) { 228 if (tuple == null) { 229 return null; 230 } 231 ServiceDescription servDescription = tuple.getServiceDescription(); 232 if (servDescription != null) { 233 Version version = servDescription.getVersion(); 234 if (version != null) { 235 return version.getValue(); 236 } 237 } 238 return null; 239 } 240 241 /** 242 * Get the service description from the given tuple. 243 */ getTupleServiceDescription(Tuple tuple)244 public static String getTupleServiceDescription(Tuple tuple) { 245 if (tuple == null) { 246 return null; 247 } 248 ServiceDescription servDescription = tuple.getServiceDescription(); 249 if (servDescription != null) { 250 Description description = servDescription.getDescription(); 251 if (description != null) { 252 return description.getValue(); 253 } 254 } 255 return null; 256 } 257 258 /** 259 * Get the contact from the given tuple. 260 */ getTupleContact(Tuple tuple)261 public static String getTupleContact(Tuple tuple) { 262 if (tuple == null) { 263 return null; 264 } 265 Contact contact = tuple.getContact(); 266 if (contact != null) { 267 return contact.getContact(); 268 } 269 return null; 270 } 271 272 /** 273 * Get the timestamp from the given tuple. 274 */ getTupleTimestamp(Tuple tuple)275 public static String getTupleTimestamp(Tuple tuple) { 276 if (tuple == null) { 277 return null; 278 } 279 Timestamp timestamp = tuple.getTimestamp(); 280 if (timestamp != null) { 281 return timestamp.getValue(); 282 } 283 return null; 284 } 285 286 /** 287 * Get the malformed status from the given tuple. 288 */ getTupleMalformedStatus(Tuple tuple)289 public static boolean getTupleMalformedStatus(Tuple tuple) { 290 if (tuple == null) { 291 return false; 292 } 293 return tuple.getMalformed(); 294 } 295 296 /** 297 * Get the terminated capability which disable all the capabilities. 298 */ getTerminatedCapability(Uri contact, String reason)299 public static RcsContactUceCapability getTerminatedCapability(Uri contact, String reason) { 300 if (reason == null) reason = ""; 301 int requestResult = (Arrays.stream(REQUEST_RESULT_REASON_NOT_FOUND) 302 .anyMatch(reason::equalsIgnoreCase) == true) ? 303 RcsContactUceCapability.REQUEST_RESULT_NOT_FOUND : 304 RcsContactUceCapability.REQUEST_RESULT_UNKNOWN; 305 306 RcsContactUceCapability.PresenceBuilder builder = 307 new RcsContactUceCapability.PresenceBuilder( 308 contact, RcsContactUceCapability.SOURCE_TYPE_NETWORK, requestResult); 309 return builder.build(); 310 } 311 312 /** 313 * Get the RcsContactUceCapability instance which the request result is NOT FOUND. 314 */ getNotFoundContactCapabilities(Uri contact)315 public static RcsContactUceCapability getNotFoundContactCapabilities(Uri contact) { 316 RcsContactUceCapability.PresenceBuilder builder = 317 new RcsContactUceCapability.PresenceBuilder(contact, 318 RcsContactUceCapability.SOURCE_TYPE_NETWORK, 319 RcsContactUceCapability.REQUEST_RESULT_NOT_FOUND); 320 return builder.build(); 321 } 322 } 323