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.capabilities; 18 19 import android.annotation.StringDef; 20 import android.text.TextUtils; 21 22 import com.android.ims.rcs.uce.presence.pidfparser.ElementBase; 23 24 import java.io.IOException; 25 import java.lang.annotation.Retention; 26 import java.lang.annotation.RetentionPolicy; 27 import java.util.ArrayList; 28 import java.util.Collections; 29 import java.util.List; 30 31 import org.xmlpull.v1.XmlPullParser; 32 import org.xmlpull.v1.XmlPullParserException; 33 import org.xmlpull.v1.XmlSerializer; 34 35 /** 36 * The "duplex" element indicates how the communication service send and receive media. It can 37 * contain two elements: "supported" and "notsupported." The supported and 38 * nonsupported elements can contains four elements: "full", "half", "receive-only" and 39 * "send-only". 40 */ 41 public class Duplex extends ElementBase { 42 /** The name of the duplex element */ 43 public static final String ELEMENT_NAME = "duplex"; 44 45 /** The name of the supported element */ 46 public static final String ELEMENT_SUPPORTED = "supported"; 47 48 /** The name of the notsupported element */ 49 public static final String ELEMENT_NOT_SUPPORTED = "notsupported"; 50 51 /** The device can simultaneously send and receive media */ 52 public static final String DUPLEX_FULL = "full"; 53 54 /** The service can alternate between sending and receiving media.*/ 55 public static final String DUPLEX_HALF = "half"; 56 57 /** The service can only receive media */ 58 public static final String DUPLEX_RECEIVE_ONLY = "receive-only"; 59 60 /** The service can only send media */ 61 public static final String DUPLEX_SEND_ONLY = "send-only"; 62 63 @StringDef(value = { 64 DUPLEX_FULL, 65 DUPLEX_HALF, 66 DUPLEX_RECEIVE_ONLY, 67 DUPLEX_SEND_ONLY}) 68 @Retention(RetentionPolicy.SOURCE) 69 public @interface DuplexType {} 70 71 private final List<String> mSupportedTypeList = new ArrayList<>(); 72 private final List<String> mNotSupportedTypeList = new ArrayList<>(); 73 Duplex()74 public Duplex() { 75 } 76 77 @Override initNamespace()78 protected String initNamespace() { 79 return CapsConstant.NAMESPACE; 80 } 81 82 @Override initElementName()83 protected String initElementName() { 84 return ELEMENT_NAME; 85 } 86 addSupportedType(@uplexType String type)87 public void addSupportedType(@DuplexType String type) { 88 mSupportedTypeList.add(type); 89 } 90 getSupportedTypes()91 public List<String> getSupportedTypes() { 92 return Collections.unmodifiableList(mSupportedTypeList); 93 } 94 addNotSupportedType(@uplexType String type)95 public void addNotSupportedType(@DuplexType String type) { 96 mNotSupportedTypeList.add(type); 97 } 98 getNotSupportedTypes()99 public List<String> getNotSupportedTypes() { 100 return Collections.unmodifiableList(mNotSupportedTypeList); 101 } 102 103 @Override serialize(XmlSerializer serializer)104 public void serialize(XmlSerializer serializer) throws IOException { 105 if (mSupportedTypeList.isEmpty() && mNotSupportedTypeList.isEmpty()) { 106 return; 107 } 108 String namespace = getNamespace(); 109 String elementName = getElementName(); 110 serializer.startTag(namespace, elementName); 111 for (String supportedType : mSupportedTypeList) { 112 serializer.startTag(namespace, ELEMENT_SUPPORTED); 113 serializer.startTag(namespace, supportedType); 114 serializer.endTag(namespace, supportedType); 115 serializer.endTag(namespace, ELEMENT_SUPPORTED); 116 } 117 for (String notSupportedType : mNotSupportedTypeList) { 118 serializer.startTag(namespace, ELEMENT_NOT_SUPPORTED); 119 serializer.startTag(namespace, notSupportedType); 120 serializer.endTag(namespace, notSupportedType); 121 serializer.endTag(namespace, ELEMENT_NOT_SUPPORTED); 122 } 123 serializer.endTag(namespace, elementName); 124 } 125 126 @Override parse(XmlPullParser parser)127 public void parse(XmlPullParser parser) throws IOException, XmlPullParserException { 128 String namespace = parser.getNamespace(); 129 String name = parser.getName(); 130 131 if (!verifyParsingElement(namespace, name)) { 132 throw new XmlPullParserException("Incorrect element: " + namespace + ", " + name); 133 } 134 135 // Move to the next event. 136 int eventType = parser.next(); 137 138 while(!(eventType == XmlPullParser.END_TAG 139 && getNamespace().equals(parser.getNamespace()) 140 && getElementName().equals(parser.getName()))) { 141 142 if (eventType == XmlPullParser.START_TAG) { 143 String tagName = parser.getName(); 144 145 if (ELEMENT_SUPPORTED.equals(tagName)) { 146 String duplexType = getDuplexType(parser); 147 if (!TextUtils.isEmpty(duplexType)) { 148 addSupportedType(duplexType); 149 } 150 } else if (ELEMENT_NOT_SUPPORTED.equals(tagName)) { 151 String duplexType = getDuplexType(parser); 152 if (!TextUtils.isEmpty(duplexType)) { 153 addNotSupportedType(duplexType); 154 } 155 } 156 } 157 158 eventType = parser.next(); 159 160 // Leave directly if the event type is the end of the document. 161 if (eventType == XmlPullParser.END_DOCUMENT) { 162 return; 163 } 164 } 165 } 166 getDuplexType(XmlPullParser parser)167 private String getDuplexType(XmlPullParser parser) throws IOException, XmlPullParserException { 168 // Move to the next event 169 int eventType = parser.next(); 170 171 String name = parser.getName(); 172 if (eventType == XmlPullParser.START_TAG) { 173 if (DUPLEX_FULL.equals(name) || 174 DUPLEX_HALF.equals(name) || 175 DUPLEX_RECEIVE_ONLY.equals(name) || 176 DUPLEX_SEND_ONLY.equals(name)) { 177 return name; 178 } 179 } 180 return null; 181 } 182 } 183