1 /* 2 * Copyright (C) 2014 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.internal.telephony.test; 18 19 import android.os.Bundle; 20 import android.telephony.ims.ImsConferenceState; 21 import android.util.Log; 22 import android.util.Xml; 23 24 import com.android.internal.telephony.util.XmlUtils; 25 26 import org.xmlpull.v1.XmlPullParser; 27 import org.xmlpull.v1.XmlPullParserException; 28 29 import java.io.IOException; 30 import java.io.InputStream; 31 32 /** 33 * Implements a basic XML parser used to parse test IMS conference event packages which can be 34 * injected into the IMS framework via the {@link com.android.internal.telephony.TelephonyTester}. 35 * <pre> 36 * {@code 37 * <xml> 38 * <participant> 39 * <user>tel:+16505551212</user> 40 * <display-text>Joe Q. Public</display-text> 41 * <endpoint>sip:+16505551212@ims-test-provider.com</endpoint> 42 * <status>connected</status> 43 * </participant> 44 * </xml> 45 * } 46 * </pre> 47 * <p> 48 * Note: This XML format is similar to the information stored in the 49 * {@link ImsConferenceState} parcelable. The {@code status} values expected in the 50 * XML are those found in the {@code ImsConferenceState} class (e.g. 51 * {@link ImsConferenceState#STATUS_CONNECTED}). 52 * <p> 53 * Place a file formatted similar to above in /data/data/com.android.phone/files/ and invoke the 54 * following command while you have an ongoing IMS call: 55 * <pre> 56 * adb shell am broadcast 57 * -a com.android.internal.telephony.TestConferenceEventPackage 58 * -e filename test.xml 59 * </pre> 60 */ 61 public class TestConferenceEventPackageParser { 62 private static final String LOG_TAG = "TestConferenceEventPackageParser"; 63 private static final String PARTICIPANT_TAG = "participant"; 64 65 /** 66 * The XML input stream to parse. 67 */ 68 private InputStream mInputStream; 69 70 /** 71 * Constructs an input of the conference event package parser for the given input stream. 72 * 73 * @param inputStream The input stream. 74 */ TestConferenceEventPackageParser(InputStream inputStream)75 public TestConferenceEventPackageParser(InputStream inputStream) { 76 mInputStream = inputStream; 77 } 78 79 /** 80 * Parses the conference event package XML file and returns an 81 * {@link ImsConferenceState} instance containing the participants described in 82 * the XML file. 83 * 84 * @return The {@link ImsConferenceState} instance. 85 */ parse()86 public ImsConferenceState parse() { 87 ImsConferenceState conferenceState = new ImsConferenceState(); 88 89 XmlPullParser parser; 90 try { 91 parser = Xml.newPullParser(); 92 parser.setInput(mInputStream, null); 93 parser.nextTag(); 94 95 int outerDepth = parser.getDepth(); 96 while (XmlUtils.nextElementWithin(parser, outerDepth)) { 97 if (parser.getName().equals(PARTICIPANT_TAG)) { 98 Log.v(LOG_TAG, "Found participant."); 99 Bundle participant = parseParticipant(parser); 100 conferenceState.mParticipants.put(participant.getString( 101 ImsConferenceState.ENDPOINT), participant); 102 } 103 } 104 } catch (IOException | XmlPullParserException e) { 105 Log.e(LOG_TAG, "Failed to read test conference event package from XML file", e); 106 return null; 107 } finally { 108 try { 109 mInputStream.close(); 110 } catch (IOException e) { 111 Log.e(LOG_TAG, "Failed to close test conference event package InputStream", e); 112 return null; 113 } 114 } 115 116 return conferenceState; 117 } 118 119 /** 120 * Parses a participant record from a conference event package XML file. 121 * 122 * @param parser The XML parser. 123 * @return {@link Bundle} containing the participant information. 124 */ parseParticipant(XmlPullParser parser)125 private Bundle parseParticipant(XmlPullParser parser) 126 throws IOException, XmlPullParserException { 127 Bundle bundle = new Bundle(); 128 129 String user = ""; 130 String displayText = ""; 131 String endpoint = ""; 132 String status = ""; 133 134 int outerDepth = parser.getDepth(); 135 while (XmlUtils.nextElementWithin(parser, outerDepth)) { 136 if (parser.getName().equals(ImsConferenceState.USER)) { 137 parser.next(); 138 user = parser.getText(); 139 } else if (parser.getName().equals(ImsConferenceState.DISPLAY_TEXT)) { 140 parser.next(); 141 displayText = parser.getText(); 142 } else if (parser.getName().equals(ImsConferenceState.ENDPOINT)) { 143 parser.next(); 144 endpoint = parser.getText(); 145 } else if (parser.getName().equals(ImsConferenceState.STATUS)) { 146 parser.next(); 147 status = parser.getText(); 148 } 149 } 150 151 Log.v(LOG_TAG, "User: "+user); 152 Log.v(LOG_TAG, "DisplayText: "+displayText); 153 Log.v(LOG_TAG, "Endpoint: "+endpoint); 154 Log.v(LOG_TAG, "Status: "+status); 155 156 bundle.putString(ImsConferenceState.USER, user); 157 bundle.putString(ImsConferenceState.DISPLAY_TEXT, displayText); 158 bundle.putString(ImsConferenceState.ENDPOINT, endpoint); 159 bundle.putString(ImsConferenceState.STATUS, status); 160 161 return bundle; 162 } 163 } 164