Loading src/java/com/android/ims/rcs/uce/presence/pidfparser/PidfParser.java +29 −15 Original line number Diff line number Diff line Loading @@ -21,10 +21,10 @@ import android.net.Uri; import android.telephony.ims.RcsContactPresenceTuple; import android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities; import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.RcsContactUceCapability.PresenceBuilder; import android.text.TextUtils; import android.util.Log; import com.android.ims.rcs.uce.presence.pidfparser.capabilities.Audio; import com.android.ims.rcs.uce.presence.pidfparser.capabilities.CapsConstant; import com.android.ims.rcs.uce.presence.pidfparser.capabilities.Duplex; Loading @@ -35,6 +35,7 @@ import com.android.ims.rcs.uce.presence.pidfparser.pidf.Basic; import com.android.ims.rcs.uce.presence.pidfparser.pidf.PidfConstant; import com.android.ims.rcs.uce.presence.pidfparser.pidf.Presence; import com.android.ims.rcs.uce.presence.pidfparser.pidf.Tuple; import com.android.ims.rcs.uce.presence.pidfparser.RcsContactUceCapabilityWrapper; import com.android.ims.rcs.uce.util.UceUtils; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -120,11 +121,12 @@ public class PidfParser { } /** * Get the RcsContactUceCapability from the given PIDF xml format. * Get the RcsContactUceCapabilityWrapper from the given PIDF xml format. */ public static @Nullable RcsContactUceCapability getRcsContactUceCapability(String pidf) { public static @Nullable RcsContactUceCapabilityWrapper getRcsContactUceCapabilityWrapper( String pidf) { if (TextUtils.isEmpty(pidf)) { Log.w(LOG_TAG, "getRcsContactUceCapability: The given pidf is empty"); Log.w(LOG_TAG, "getRcsContactUceCapabilityWrapper: The given pidf is empty"); return null; } Loading @@ -132,7 +134,7 @@ public class PidfParser { Matcher matcher = PIDF_PATTERN.matcher(pidf); String formattedPidf = matcher.replaceAll(""); if (TextUtils.isEmpty(formattedPidf)) { Log.w(LOG_TAG, "getRcsContactUceCapability: The formatted pidf is empty"); Log.w(LOG_TAG, "getRcsContactUceCapabilityWrapper: The formatted pidf is empty"); return null; } Loading @@ -147,7 +149,7 @@ public class PidfParser { // Start parsing Presence presence = parsePidf(parser); // Convert from the Presence to the RcsContactUceCapability // Convert from the Presence to the RcsContactUceCapabilityWrapper return convertToRcsContactUceCapability(presence); } catch (XmlPullParserException | IOException e) { Loading @@ -168,10 +170,12 @@ public class PidfParser { XmlPullParserException { Presence presence = null; int nextType = parser.next(); boolean findPresenceTag = false; do { // Find the Presence start tag if (nextType == XmlPullParser.START_TAG && Presence.ELEMENT_NAME.equals(parser.getName())) { findPresenceTag = true; presence = new Presence(); presence.parse(parser); break; Loading @@ -179,13 +183,18 @@ public class PidfParser { nextType = parser.next(); } while(nextType != XmlPullParser.END_DOCUMENT); if (!findPresenceTag) { Log.w(LOG_TAG, "parsePidf: The presence start tag not found."); } return presence; } /* * Convert the given Presence to the RcsContactUceCapability * Convert the given Presence to the RcsContactUceCapabilityWrapper */ private static RcsContactUceCapability convertToRcsContactUceCapability(Presence presence) { private static RcsContactUceCapabilityWrapper convertToRcsContactUceCapability( Presence presence) { if (presence == null) { Log.w(LOG_TAG, "convertToRcsContactUceCapability: The presence is null"); return null; Loading @@ -195,19 +204,24 @@ public class PidfParser { return null; } PresenceBuilder presenceBuilder = new PresenceBuilder(Uri.parse(presence.getEntity()), RcsContactUceCapability.SOURCE_TYPE_NETWORK, RcsContactUceCapabilityWrapper uceCapabilityWrapper = new RcsContactUceCapabilityWrapper( Uri.parse(presence.getEntity()), RcsContactUceCapability.SOURCE_TYPE_NETWORK, RcsContactUceCapability.REQUEST_RESULT_FOUND); // Add all the capability tuples of this contact presence.getTupleList().forEach(tuple -> { // The tuple that fails parsing is invalid data, so discard it. if (!tuple.getMalformed()) { RcsContactPresenceTuple capabilityTuple = getRcsContactPresenceTuple(tuple); if (capabilityTuple != null) { presenceBuilder.addCapabilityTuple(capabilityTuple); uceCapabilityWrapper.addCapabilityTuple(capabilityTuple); } } else { uceCapabilityWrapper.setMalformedContents(); } }); presenceBuilder.setEntityUri(Uri.parse(presence.getEntity())); return presenceBuilder.build(); uceCapabilityWrapper.setEntityUri(Uri.parse(presence.getEntity())); return uceCapabilityWrapper; } /* Loading src/java/com/android/ims/rcs/uce/presence/pidfparser/PidfParserUtils.java +10 −0 Original line number Diff line number Diff line Loading @@ -283,6 +283,16 @@ public class PidfParserUtils { return null; } /** * Get the malformed status from the given tuple. */ public static boolean getTupleMalformedStatus(Tuple tuple) { if (tuple == null) { return false; } return tuple.getMalformed(); } /** * Get the terminated capability which disable all the capabilities. */ Loading src/java/com/android/ims/rcs/uce/presence/pidfparser/RcsContactUceCapabilityWrapper.java 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.ims.rcs.uce.presence.pidfparser; import android.annotation.NonNull; import android.annotation.Nullable; import android.net.Uri; import android.telephony.ims.RcsContactPresenceTuple; import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.RcsContactUceCapability.PresenceBuilder; import java.util.ArrayList; import java.util.List; /** * A wrapper class that uses the parsed information to construct {@link RcsContactUceCapability} * instances. */ public class RcsContactUceCapabilityWrapper { private final Uri mContactUri; private final int mSourceType; private final int mRequestResult; private boolean mIsMalformed; private final List<RcsContactPresenceTuple> mPresenceTuples = new ArrayList<>(); private Uri mEntityUri; /** * Create the wrapper, which can be used to set UCE capabilities as well as custom * capability extensions. * @param contact The contact URI that the capabilities are attached to. * @param sourceType The type where the capabilities of this contact were retrieved from. * @param requestResult the request result */ public RcsContactUceCapabilityWrapper(@NonNull Uri contact, int sourceType, int requestResult) { mContactUri = contact; mSourceType = sourceType; mRequestResult = requestResult; mIsMalformed = false; } /** * Add the {@link RcsContactPresenceTuple} into the presence tuple list. * @param tuple The {@link RcsContactPresenceTuple} to be added into. */ public void addCapabilityTuple(@NonNull RcsContactPresenceTuple tuple) { mPresenceTuples.add(tuple); } /** * This flag is set if at least one tuple could not be parsed due to malformed contents. */ public void setMalformedContents() { mIsMalformed = true; } /** * Set the entity URI related to the contact whose capabilities were requested. * @param entityUri the 'pres' URL of the PRESENTITY publishing presence document. */ public void setEntityUri(@NonNull Uri entityUri) { mEntityUri = entityUri; } /** * Whether the XML is malformed. * @return {@code true} if all of the presence tuple information associated with * the entity URI ({@link #getEntityUri}) is malformed and there is no tuple info * available. If one or more of the tuples are still well-formed after parsing the * XML, this method will return {@code false}. */ public boolean isMalformed() { if (mIsMalformed == false) { return false; } if (mPresenceTuples.isEmpty()) { return true; } return false; } /** * Retrieve the entity URI of the contact whose presence information is being requested for. * @return the URI representing the 'pres' URL of the PRESENTITY publishing presence document * or {@code null} if the entity uri does not exist in the presence document. */ public @Nullable Uri getEntityUri() { return mEntityUri; } /** * @return a new RcsContactUceCapability instance from the contents of this wrapper. */ public @NonNull RcsContactUceCapability toRcsContactUceCapability() { PresenceBuilder presenceBuilder = new PresenceBuilder(mContactUri, mSourceType, mRequestResult); // Add all the capability tuples of this contact presenceBuilder.addCapabilityTuples(mPresenceTuples); presenceBuilder.setEntityUri(mEntityUri); return presenceBuilder.build(); } } src/java/com/android/ims/rcs/uce/presence/pidfparser/pidf/Presence.java +22 −2 Original line number Diff line number Diff line Loading @@ -18,8 +18,11 @@ package com.android.ims.rcs.uce.presence.pidfparser.pidf; import android.annotation.NonNull; import android.net.Uri; import android.text.TextUtils; import android.util.Log; import com.android.ims.rcs.uce.presence.pidfparser.ElementBase; import com.android.ims.rcs.uce.util.UceUtils; import com.android.internal.annotations.VisibleForTesting; import org.xmlpull.v1.XmlPullParser; Loading @@ -41,6 +44,7 @@ public class Presence extends ElementBase { * 2: Any number (including 0) of <note> elements * 3: Any number of OPTIONAL extension elements from other namespaces. */ private static final String LOG_TAG = UceUtils.getLogPrefix() + "Presence"; /** The name of this element */ public static final String ELEMENT_NAME = "presence"; Loading Loading @@ -133,6 +137,9 @@ public class Presence extends ElementBase { } mEntity = parser.getAttributeValue(XmlPullParser.NO_NAMESPACE, ATTRIBUTE_NAME_ENTITY); if (TextUtils.isEmpty(mEntity)) { throw new XmlPullParserException("Entity uri of presence is empty"); } // Move to the next event. int eventType = parser.next(); Loading @@ -146,11 +153,24 @@ public class Presence extends ElementBase { if (isTupleElement(eventType, tagName)) { Tuple tuple = new Tuple(); try { // If one tuple encounters an xml exception, we must parse the other tuple // and store valid information. tuple.parse(parser); } catch (XmlPullParserException e) { e.printStackTrace(); Log.w(LOG_TAG, "parse: Exception occurred during Tuple parsing."); tuple.setMalformed(true); } mTupleList.add(tuple); } else if (isNoteElement(eventType, tagName)) { Note note = new Note(); try { note.parse(parser); } catch (XmlPullParserException e) { e.printStackTrace(); Log.w(LOG_TAG, "parse: Exception occurred during Note parsing."); } mNoteList.add(note); } } Loading src/java/com/android/ims/rcs/uce/presence/pidfparser/pidf/Tuple.java +11 −0 Original line number Diff line number Diff line Loading @@ -59,8 +59,11 @@ public class Tuple extends ElementBase { private List<Note> mNoteList = new ArrayList<>(); private Timestamp mTimestamp; private boolean mMalformed; public Tuple() { mId = getTupleId(); mMalformed = false; } @Override Loading Loading @@ -121,6 +124,14 @@ public class Tuple extends ElementBase { return mTimestamp; } public void setMalformed(boolean malformed) { mMalformed = malformed; } public boolean getMalformed() { return mMalformed; } @Override public void serialize(XmlSerializer serializer) throws IOException { String namespace = getNamespace(); Loading Loading
src/java/com/android/ims/rcs/uce/presence/pidfparser/PidfParser.java +29 −15 Original line number Diff line number Diff line Loading @@ -21,10 +21,10 @@ import android.net.Uri; import android.telephony.ims.RcsContactPresenceTuple; import android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities; import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.RcsContactUceCapability.PresenceBuilder; import android.text.TextUtils; import android.util.Log; import com.android.ims.rcs.uce.presence.pidfparser.capabilities.Audio; import com.android.ims.rcs.uce.presence.pidfparser.capabilities.CapsConstant; import com.android.ims.rcs.uce.presence.pidfparser.capabilities.Duplex; Loading @@ -35,6 +35,7 @@ import com.android.ims.rcs.uce.presence.pidfparser.pidf.Basic; import com.android.ims.rcs.uce.presence.pidfparser.pidf.PidfConstant; import com.android.ims.rcs.uce.presence.pidfparser.pidf.Presence; import com.android.ims.rcs.uce.presence.pidfparser.pidf.Tuple; import com.android.ims.rcs.uce.presence.pidfparser.RcsContactUceCapabilityWrapper; import com.android.ims.rcs.uce.util.UceUtils; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -120,11 +121,12 @@ public class PidfParser { } /** * Get the RcsContactUceCapability from the given PIDF xml format. * Get the RcsContactUceCapabilityWrapper from the given PIDF xml format. */ public static @Nullable RcsContactUceCapability getRcsContactUceCapability(String pidf) { public static @Nullable RcsContactUceCapabilityWrapper getRcsContactUceCapabilityWrapper( String pidf) { if (TextUtils.isEmpty(pidf)) { Log.w(LOG_TAG, "getRcsContactUceCapability: The given pidf is empty"); Log.w(LOG_TAG, "getRcsContactUceCapabilityWrapper: The given pidf is empty"); return null; } Loading @@ -132,7 +134,7 @@ public class PidfParser { Matcher matcher = PIDF_PATTERN.matcher(pidf); String formattedPidf = matcher.replaceAll(""); if (TextUtils.isEmpty(formattedPidf)) { Log.w(LOG_TAG, "getRcsContactUceCapability: The formatted pidf is empty"); Log.w(LOG_TAG, "getRcsContactUceCapabilityWrapper: The formatted pidf is empty"); return null; } Loading @@ -147,7 +149,7 @@ public class PidfParser { // Start parsing Presence presence = parsePidf(parser); // Convert from the Presence to the RcsContactUceCapability // Convert from the Presence to the RcsContactUceCapabilityWrapper return convertToRcsContactUceCapability(presence); } catch (XmlPullParserException | IOException e) { Loading @@ -168,10 +170,12 @@ public class PidfParser { XmlPullParserException { Presence presence = null; int nextType = parser.next(); boolean findPresenceTag = false; do { // Find the Presence start tag if (nextType == XmlPullParser.START_TAG && Presence.ELEMENT_NAME.equals(parser.getName())) { findPresenceTag = true; presence = new Presence(); presence.parse(parser); break; Loading @@ -179,13 +183,18 @@ public class PidfParser { nextType = parser.next(); } while(nextType != XmlPullParser.END_DOCUMENT); if (!findPresenceTag) { Log.w(LOG_TAG, "parsePidf: The presence start tag not found."); } return presence; } /* * Convert the given Presence to the RcsContactUceCapability * Convert the given Presence to the RcsContactUceCapabilityWrapper */ private static RcsContactUceCapability convertToRcsContactUceCapability(Presence presence) { private static RcsContactUceCapabilityWrapper convertToRcsContactUceCapability( Presence presence) { if (presence == null) { Log.w(LOG_TAG, "convertToRcsContactUceCapability: The presence is null"); return null; Loading @@ -195,19 +204,24 @@ public class PidfParser { return null; } PresenceBuilder presenceBuilder = new PresenceBuilder(Uri.parse(presence.getEntity()), RcsContactUceCapability.SOURCE_TYPE_NETWORK, RcsContactUceCapabilityWrapper uceCapabilityWrapper = new RcsContactUceCapabilityWrapper( Uri.parse(presence.getEntity()), RcsContactUceCapability.SOURCE_TYPE_NETWORK, RcsContactUceCapability.REQUEST_RESULT_FOUND); // Add all the capability tuples of this contact presence.getTupleList().forEach(tuple -> { // The tuple that fails parsing is invalid data, so discard it. if (!tuple.getMalformed()) { RcsContactPresenceTuple capabilityTuple = getRcsContactPresenceTuple(tuple); if (capabilityTuple != null) { presenceBuilder.addCapabilityTuple(capabilityTuple); uceCapabilityWrapper.addCapabilityTuple(capabilityTuple); } } else { uceCapabilityWrapper.setMalformedContents(); } }); presenceBuilder.setEntityUri(Uri.parse(presence.getEntity())); return presenceBuilder.build(); uceCapabilityWrapper.setEntityUri(Uri.parse(presence.getEntity())); return uceCapabilityWrapper; } /* Loading
src/java/com/android/ims/rcs/uce/presence/pidfparser/PidfParserUtils.java +10 −0 Original line number Diff line number Diff line Loading @@ -283,6 +283,16 @@ public class PidfParserUtils { return null; } /** * Get the malformed status from the given tuple. */ public static boolean getTupleMalformedStatus(Tuple tuple) { if (tuple == null) { return false; } return tuple.getMalformed(); } /** * Get the terminated capability which disable all the capabilities. */ Loading
src/java/com/android/ims/rcs/uce/presence/pidfparser/RcsContactUceCapabilityWrapper.java 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.ims.rcs.uce.presence.pidfparser; import android.annotation.NonNull; import android.annotation.Nullable; import android.net.Uri; import android.telephony.ims.RcsContactPresenceTuple; import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.RcsContactUceCapability.PresenceBuilder; import java.util.ArrayList; import java.util.List; /** * A wrapper class that uses the parsed information to construct {@link RcsContactUceCapability} * instances. */ public class RcsContactUceCapabilityWrapper { private final Uri mContactUri; private final int mSourceType; private final int mRequestResult; private boolean mIsMalformed; private final List<RcsContactPresenceTuple> mPresenceTuples = new ArrayList<>(); private Uri mEntityUri; /** * Create the wrapper, which can be used to set UCE capabilities as well as custom * capability extensions. * @param contact The contact URI that the capabilities are attached to. * @param sourceType The type where the capabilities of this contact were retrieved from. * @param requestResult the request result */ public RcsContactUceCapabilityWrapper(@NonNull Uri contact, int sourceType, int requestResult) { mContactUri = contact; mSourceType = sourceType; mRequestResult = requestResult; mIsMalformed = false; } /** * Add the {@link RcsContactPresenceTuple} into the presence tuple list. * @param tuple The {@link RcsContactPresenceTuple} to be added into. */ public void addCapabilityTuple(@NonNull RcsContactPresenceTuple tuple) { mPresenceTuples.add(tuple); } /** * This flag is set if at least one tuple could not be parsed due to malformed contents. */ public void setMalformedContents() { mIsMalformed = true; } /** * Set the entity URI related to the contact whose capabilities were requested. * @param entityUri the 'pres' URL of the PRESENTITY publishing presence document. */ public void setEntityUri(@NonNull Uri entityUri) { mEntityUri = entityUri; } /** * Whether the XML is malformed. * @return {@code true} if all of the presence tuple information associated with * the entity URI ({@link #getEntityUri}) is malformed and there is no tuple info * available. If one or more of the tuples are still well-formed after parsing the * XML, this method will return {@code false}. */ public boolean isMalformed() { if (mIsMalformed == false) { return false; } if (mPresenceTuples.isEmpty()) { return true; } return false; } /** * Retrieve the entity URI of the contact whose presence information is being requested for. * @return the URI representing the 'pres' URL of the PRESENTITY publishing presence document * or {@code null} if the entity uri does not exist in the presence document. */ public @Nullable Uri getEntityUri() { return mEntityUri; } /** * @return a new RcsContactUceCapability instance from the contents of this wrapper. */ public @NonNull RcsContactUceCapability toRcsContactUceCapability() { PresenceBuilder presenceBuilder = new PresenceBuilder(mContactUri, mSourceType, mRequestResult); // Add all the capability tuples of this contact presenceBuilder.addCapabilityTuples(mPresenceTuples); presenceBuilder.setEntityUri(mEntityUri); return presenceBuilder.build(); } }
src/java/com/android/ims/rcs/uce/presence/pidfparser/pidf/Presence.java +22 −2 Original line number Diff line number Diff line Loading @@ -18,8 +18,11 @@ package com.android.ims.rcs.uce.presence.pidfparser.pidf; import android.annotation.NonNull; import android.net.Uri; import android.text.TextUtils; import android.util.Log; import com.android.ims.rcs.uce.presence.pidfparser.ElementBase; import com.android.ims.rcs.uce.util.UceUtils; import com.android.internal.annotations.VisibleForTesting; import org.xmlpull.v1.XmlPullParser; Loading @@ -41,6 +44,7 @@ public class Presence extends ElementBase { * 2: Any number (including 0) of <note> elements * 3: Any number of OPTIONAL extension elements from other namespaces. */ private static final String LOG_TAG = UceUtils.getLogPrefix() + "Presence"; /** The name of this element */ public static final String ELEMENT_NAME = "presence"; Loading Loading @@ -133,6 +137,9 @@ public class Presence extends ElementBase { } mEntity = parser.getAttributeValue(XmlPullParser.NO_NAMESPACE, ATTRIBUTE_NAME_ENTITY); if (TextUtils.isEmpty(mEntity)) { throw new XmlPullParserException("Entity uri of presence is empty"); } // Move to the next event. int eventType = parser.next(); Loading @@ -146,11 +153,24 @@ public class Presence extends ElementBase { if (isTupleElement(eventType, tagName)) { Tuple tuple = new Tuple(); try { // If one tuple encounters an xml exception, we must parse the other tuple // and store valid information. tuple.parse(parser); } catch (XmlPullParserException e) { e.printStackTrace(); Log.w(LOG_TAG, "parse: Exception occurred during Tuple parsing."); tuple.setMalformed(true); } mTupleList.add(tuple); } else if (isNoteElement(eventType, tagName)) { Note note = new Note(); try { note.parse(parser); } catch (XmlPullParserException e) { e.printStackTrace(); Log.w(LOG_TAG, "parse: Exception occurred during Note parsing."); } mNoteList.add(note); } } Loading
src/java/com/android/ims/rcs/uce/presence/pidfparser/pidf/Tuple.java +11 −0 Original line number Diff line number Diff line Loading @@ -59,8 +59,11 @@ public class Tuple extends ElementBase { private List<Note> mNoteList = new ArrayList<>(); private Timestamp mTimestamp; private boolean mMalformed; public Tuple() { mId = getTupleId(); mMalformed = false; } @Override Loading Loading @@ -121,6 +124,14 @@ public class Tuple extends ElementBase { return mTimestamp; } public void setMalformed(boolean malformed) { mMalformed = malformed; } public boolean getMalformed() { return mMalformed; } @Override public void serialize(XmlSerializer serializer) throws IOException { String namespace = getNamespace(); Loading