• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.mms.service;
18 
19 import org.xmlpull.v1.XmlPullParser;
20 import org.xmlpull.v1.XmlPullParserException;
21 
22 import android.content.ContentValues;
23 import android.util.Log;
24 
25 import java.io.IOException;
26 
27 /*
28  * XML processor for mms_config.xml
29  */
30 public class MmsConfigXmlProcessor {
31     private static final String TAG = MmsService.TAG;
32 
33     public interface MmsConfigHandler {
process(String key, String value, String type)34         public void process(String key, String value, String type);
35     }
36 
37     private static final String TAG_MMS_CONFIG = "mms_config";
38 
39     // Handler to process one mms_config key/value pair
40     private MmsConfigHandler mMmsConfigHandler;
41 
42     private final StringBuilder mLogStringBuilder = new StringBuilder();
43 
44     private final XmlPullParser mInputParser;
45 
MmsConfigXmlProcessor(XmlPullParser parser)46     private MmsConfigXmlProcessor(XmlPullParser parser) {
47         mInputParser = parser;
48         mMmsConfigHandler = null;
49     }
50 
get(XmlPullParser parser)51     public static MmsConfigXmlProcessor get(XmlPullParser parser) {
52         return new MmsConfigXmlProcessor(parser);
53     }
54 
setMmsConfigHandler(MmsConfigHandler handler)55     public MmsConfigXmlProcessor setMmsConfigHandler(MmsConfigHandler handler) {
56         mMmsConfigHandler = handler;
57         return this;
58     }
59 
60     /**
61      * Move XML parser forward to next event type or the end of doc
62      *
63      * @param eventType
64      * @return The final event type we meet
65      * @throws org.xmlpull.v1.XmlPullParserException
66      * @throws java.io.IOException
67      */
advanceToNextEvent(int eventType)68     private int advanceToNextEvent(int eventType) throws XmlPullParserException, IOException {
69         for (;;) {
70             int nextEvent = mInputParser.next();
71             if (nextEvent == eventType
72                     || nextEvent == XmlPullParser.END_DOCUMENT) {
73                 return nextEvent;
74             }
75         }
76     }
77 
process()78     public void process() {
79         try {
80             // Find the first element
81             if (advanceToNextEvent(XmlPullParser.START_TAG) != XmlPullParser.START_TAG) {
82                 throw new XmlPullParserException("MmsConfigXmlProcessor: expecting start tag @"
83                         + xmlParserDebugContext());
84             }
85             // A single ContentValues object for holding the parsing result of
86             // an apn element
87             final ContentValues values = new ContentValues();
88             String tagName = mInputParser.getName();
89             // Top level tag can be "apns" (apns.xml, or APN OTA XML)
90             // or "mms_config" (mms_config.xml)
91             if (TAG_MMS_CONFIG.equals(tagName)) {
92                 // mms_config.xml resource
93                 processMmsConfig();
94             }
95         } catch (IOException e) {
96             Log.e(TAG, "MmsConfigXmlProcessor: I/O failure " + e, e);
97         } catch (XmlPullParserException e) {
98             Log.e(TAG, "MmsConfigXmlProcessor: parsing failure " + e, e);
99         }
100     }
101 
xmlParserEventString(int event)102     private static String xmlParserEventString(int event) {
103         switch (event) {
104             case XmlPullParser.START_DOCUMENT: return "START_DOCUMENT";
105             case XmlPullParser.END_DOCUMENT: return "END_DOCUMENT";
106             case XmlPullParser.START_TAG: return "START_TAG";
107             case XmlPullParser.END_TAG: return "END_TAG";
108             case XmlPullParser.TEXT: return "TEXT";
109         }
110         return Integer.toString(event);
111     }
112 
113     /**
114      * @return The debugging information of the parser's current position
115      */
xmlParserDebugContext()116     private String xmlParserDebugContext() {
117         mLogStringBuilder.setLength(0);
118         if (mInputParser != null) {
119             try {
120                 final int eventType = mInputParser.getEventType();
121                 mLogStringBuilder.append(xmlParserEventString(eventType));
122                 if (eventType == XmlPullParser.START_TAG
123                         || eventType == XmlPullParser.END_TAG
124                         || eventType == XmlPullParser.TEXT) {
125                     mLogStringBuilder.append('<').append(mInputParser.getName());
126                     for (int i = 0; i < mInputParser.getAttributeCount(); i++) {
127                         mLogStringBuilder.append(' ')
128                             .append(mInputParser.getAttributeName(i))
129                             .append('=')
130                             .append(mInputParser.getAttributeValue(i));
131                     }
132                     mLogStringBuilder.append("/>");
133                 }
134                 return mLogStringBuilder.toString();
135             } catch (XmlPullParserException e) {
136                 Log.e(TAG, "xmlParserDebugContext: " + e, e);
137             }
138         }
139         return "Unknown";
140     }
141 
142     /**
143      * Process one mms_config.
144      *
145      * @throws java.io.IOException
146      * @throws org.xmlpull.v1.XmlPullParserException
147      */
processMmsConfig()148     private void processMmsConfig()
149             throws IOException, XmlPullParserException {
150         // We are at the start tag
151         for (;;) {
152             int nextEvent;
153             // Skipping spaces
154             while ((nextEvent = mInputParser.next()) == XmlPullParser.TEXT);
155             if (nextEvent == XmlPullParser.START_TAG) {
156                 // Parse one mms config key/value
157                 processMmsConfigKeyValue();
158             } else if (nextEvent == XmlPullParser.END_TAG) {
159                 break;
160             } else {
161                 throw new XmlPullParserException("MmsConfig: expecting start or end tag @"
162                         + xmlParserDebugContext());
163             }
164         }
165     }
166 
167     /**
168      * Process one mms_config key/value pair
169      *
170      * @throws java.io.IOException
171      * @throws org.xmlpull.v1.XmlPullParserException
172      */
processMmsConfigKeyValue()173     private void processMmsConfigKeyValue() throws IOException, XmlPullParserException {
174         final String key = mInputParser.getAttributeValue(null, "name");
175         // We are at the start tag, the name of the tag is the type
176         // e.g. <int name="key">value</int>
177         final String type = mInputParser.getName();
178         int nextEvent = mInputParser.next();
179         String value = null;
180         if (nextEvent == XmlPullParser.TEXT) {
181             value = mInputParser.getText();
182             nextEvent = mInputParser.next();
183         }
184         if (nextEvent != XmlPullParser.END_TAG) {
185             throw new XmlPullParserException("MmsConfigXmlProcessor: expecting end tag @"
186                     + xmlParserDebugContext());
187         }
188         if (MmsConfig.isValidKey(key, type)) {
189             // We are done parsing one mms_config key/value, call the handler
190             if (mMmsConfigHandler != null) {
191                 mMmsConfigHandler.process(key, value, type);
192             }
193         } else {
194             Log.w(TAG, "MmsConfig: invalid key=" + key + " or type=" + type);
195         }
196     }
197 }
198