| /* |
| * Copyright (C) 2014 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.mms.service; |
| |
| import org.xmlpull.v1.XmlPullParser; |
| import org.xmlpull.v1.XmlPullParserException; |
| |
| import android.content.ContentValues; |
| import android.util.Log; |
| |
| import java.io.IOException; |
| |
| /* |
| * XML processor for mms_config.xml |
| */ |
| public class MmsConfigXmlProcessor { |
| private static final String TAG = MmsService.TAG; |
| |
| public interface MmsConfigHandler { |
| public void process(String key, String value, String type); |
| } |
| |
| private static final String TAG_MMS_CONFIG = "mms_config"; |
| |
| // Handler to process one mms_config key/value pair |
| private MmsConfigHandler mMmsConfigHandler; |
| |
| private final StringBuilder mLogStringBuilder = new StringBuilder(); |
| |
| private final XmlPullParser mInputParser; |
| |
| private MmsConfigXmlProcessor(XmlPullParser parser) { |
| mInputParser = parser; |
| mMmsConfigHandler = null; |
| } |
| |
| public static MmsConfigXmlProcessor get(XmlPullParser parser) { |
| return new MmsConfigXmlProcessor(parser); |
| } |
| |
| public MmsConfigXmlProcessor setMmsConfigHandler(MmsConfigHandler handler) { |
| mMmsConfigHandler = handler; |
| return this; |
| } |
| |
| /** |
| * Move XML parser forward to next event type or the end of doc |
| * |
| * @param eventType |
| * @return The final event type we meet |
| * @throws org.xmlpull.v1.XmlPullParserException |
| * @throws java.io.IOException |
| */ |
| private int advanceToNextEvent(int eventType) throws XmlPullParserException, IOException { |
| for (;;) { |
| int nextEvent = mInputParser.next(); |
| if (nextEvent == eventType |
| || nextEvent == XmlPullParser.END_DOCUMENT) { |
| return nextEvent; |
| } |
| } |
| } |
| |
| public void process() { |
| try { |
| // Find the first element |
| if (advanceToNextEvent(XmlPullParser.START_TAG) != XmlPullParser.START_TAG) { |
| throw new XmlPullParserException("MmsConfigXmlProcessor: expecting start tag @" |
| + xmlParserDebugContext()); |
| } |
| // A single ContentValues object for holding the parsing result of |
| // an apn element |
| final ContentValues values = new ContentValues(); |
| String tagName = mInputParser.getName(); |
| // Top level tag can be "apns" (apns.xml, or APN OTA XML) |
| // or "mms_config" (mms_config.xml) |
| if (TAG_MMS_CONFIG.equals(tagName)) { |
| // mms_config.xml resource |
| processMmsConfig(); |
| } |
| } catch (IOException e) { |
| Log.e(TAG, "MmsConfigXmlProcessor: I/O failure " + e, e); |
| } catch (XmlPullParserException e) { |
| Log.e(TAG, "MmsConfigXmlProcessor: parsing failure " + e, e); |
| } |
| } |
| |
| private static String xmlParserEventString(int event) { |
| switch (event) { |
| case XmlPullParser.START_DOCUMENT: return "START_DOCUMENT"; |
| case XmlPullParser.END_DOCUMENT: return "END_DOCUMENT"; |
| case XmlPullParser.START_TAG: return "START_TAG"; |
| case XmlPullParser.END_TAG: return "END_TAG"; |
| case XmlPullParser.TEXT: return "TEXT"; |
| } |
| return Integer.toString(event); |
| } |
| |
| /** |
| * @return The debugging information of the parser's current position |
| */ |
| private String xmlParserDebugContext() { |
| mLogStringBuilder.setLength(0); |
| if (mInputParser != null) { |
| try { |
| final int eventType = mInputParser.getEventType(); |
| mLogStringBuilder.append(xmlParserEventString(eventType)); |
| if (eventType == XmlPullParser.START_TAG |
| || eventType == XmlPullParser.END_TAG |
| || eventType == XmlPullParser.TEXT) { |
| mLogStringBuilder.append('<').append(mInputParser.getName()); |
| for (int i = 0; i < mInputParser.getAttributeCount(); i++) { |
| mLogStringBuilder.append(' ') |
| .append(mInputParser.getAttributeName(i)) |
| .append('=') |
| .append(mInputParser.getAttributeValue(i)); |
| } |
| mLogStringBuilder.append("/>"); |
| } |
| return mLogStringBuilder.toString(); |
| } catch (XmlPullParserException e) { |
| Log.e(TAG, "xmlParserDebugContext: " + e, e); |
| } |
| } |
| return "Unknown"; |
| } |
| |
| /** |
| * Process one mms_config. |
| * |
| * @throws java.io.IOException |
| * @throws org.xmlpull.v1.XmlPullParserException |
| */ |
| private void processMmsConfig() |
| throws IOException, XmlPullParserException { |
| // We are at the start tag |
| for (;;) { |
| int nextEvent; |
| // Skipping spaces |
| while ((nextEvent = mInputParser.next()) == XmlPullParser.TEXT); |
| if (nextEvent == XmlPullParser.START_TAG) { |
| // Parse one mms config key/value |
| processMmsConfigKeyValue(); |
| } else if (nextEvent == XmlPullParser.END_TAG) { |
| break; |
| } else { |
| throw new XmlPullParserException("MmsConfig: expecting start or end tag @" |
| + xmlParserDebugContext()); |
| } |
| } |
| } |
| |
| /** |
| * Process one mms_config key/value pair |
| * |
| * @throws java.io.IOException |
| * @throws org.xmlpull.v1.XmlPullParserException |
| */ |
| private void processMmsConfigKeyValue() throws IOException, XmlPullParserException { |
| final String key = mInputParser.getAttributeValue(null, "name"); |
| // We are at the start tag, the name of the tag is the type |
| // e.g. <int name="key">value</int> |
| final String type = mInputParser.getName(); |
| int nextEvent = mInputParser.next(); |
| String value = null; |
| if (nextEvent == XmlPullParser.TEXT) { |
| value = mInputParser.getText(); |
| nextEvent = mInputParser.next(); |
| } |
| if (nextEvent != XmlPullParser.END_TAG) { |
| throw new XmlPullParserException("MmsConfigXmlProcessor: expecting end tag @" |
| + xmlParserDebugContext()); |
| } |
| if (MmsConfig.isValidKey(key, type)) { |
| // We are done parsing one mms_config key/value, call the handler |
| if (mMmsConfigHandler != null) { |
| mMmsConfigHandler.process(key, value, type); |
| } |
| } else { |
| Log.w(TAG, "MmsConfig: invalid key=" + key + " or type=" + type); |
| } |
| } |
| } |