summaryrefslogtreecommitdiffstats
path: root/service/java/com/android/server/wifi/hotspot2/omadm
diff options
context:
space:
mode:
authorJan Nordqvist <jannq@google.com>2016-02-10 16:46:27 -0800
committerJan Nordqvist <jannq@google.com>2016-02-13 02:07:19 +0000
commitc9b88562541a0c2acd60d0a01ac1e182e73c79f9 (patch)
tree2b8da2bcc41d3098c4181e270a7795318fba3f9f /service/java/com/android/server/wifi/hotspot2/omadm
parentb2f519476ee484d43de057ded668d05dccc5ab76 (diff)
downloadandroid_frameworks_opt_net_wifi-c9b88562541a0c2acd60d0a01ac1e182e73c79f9.tar.gz
android_frameworks_opt_net_wifi-c9b88562541a0c2acd60d0a01ac1e182e73c79f9.tar.bz2
android_frameworks_opt_net_wifi-c9b88562541a0c2acd60d0a01ac1e182e73c79f9.zip
Fixed incorrect XML serialization of MO Tree.
Bug=27145137 Change-Id: Id2016b3ca2cf8091f254b35d8e6ff9cf4a14907a
Diffstat (limited to 'service/java/com/android/server/wifi/hotspot2/omadm')
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/MOTree.java23
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/ManagementTreeRoot.java58
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/NodeAttribute.java13
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/OMAConstructed.java2
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/OMANode.java32
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/OMAParser.java4
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/OMAScalar.java4
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/PasspointManagementObjectManager.java47
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/XMLNode.java53
9 files changed, 187 insertions, 49 deletions
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/MOTree.java b/service/java/com/android/server/wifi/hotspot2/omadm/MOTree.java
index 99683adca..63541eec8 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/MOTree.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/MOTree.java
@@ -2,6 +2,7 @@ package com.android.server.wifi.hotspot2.omadm;
import org.xml.sax.SAXException;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -40,27 +41,35 @@ public class MOTree {
mUrn = urn;
mDtdRev = dtdRev;
- mRoot = new OMAConstructed(null, MgmtTreeTag, null);
+ mRoot = new ManagementTreeRoot(node, dtdRev);
for (XMLNode child : node.getChildren()) {
buildNode(mRoot, child);
}
}
- public MOTree(String urn, String rev, OMAConstructed root) throws IOException {
+ public MOTree(String urn, String rev, OMAConstructed root) {
mUrn = urn;
mDtdRev = rev;
mRoot = root;
}
- public static MOTree buildMgmtTree(String urn, String rev, OMAConstructed root) throws IOException {
+ /**
+ * Build a Passpoint OMA-DM Management Object tree object.
+ * @param urn The URN for the tree.
+ * @param rev The DTD revision for the tree.
+ * @param root The OMA-DM tree root, in all practical cases the PerProviderSubscription
+ * node.
+ * @return an MOTree object
+ */
+ public static MOTree buildMgmtTree(String urn, String rev, OMAConstructed root) {
OMAConstructed realRoot;
switch (urn) {
case OMAConstants.PPS_URN:
case OMAConstants.DevInfoURN:
case OMAConstants.DevDetailURN:
case OMAConstants.DevDetailXURN:
- realRoot = new OMAConstructed(null, MgmtTreeTag, urn, "xmlns", OMAConstants.SyncML);
+ realRoot = new ManagementTreeRoot(OMAConstants.OMAVersion);
realRoot.addChild(root);
return new MOTree(urn, rev, realRoot);
default:
@@ -232,7 +241,7 @@ public class MOTree {
for (; ; ) {
int octet = in.read();
if (octet < 0) {
- return null;
+ throw new FileNotFoundException();
} else if (octet > ' ') {
tree.append((char) octet);
strip = false;
@@ -258,11 +267,7 @@ public class MOTree {
public String toXml() {
StringBuilder sb = new StringBuilder();
-
- sb.append('<').append(MgmtTreeTag).append(">\n");
- sb.append("<VerDTD>").append(mDtdRev).append("</VerDTD>\n");
mRoot.toXml(sb);
- sb.append("</").append(MgmtTreeTag).append(">\n");
return sb.toString();
}
}
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/ManagementTreeRoot.java b/service/java/com/android/server/wifi/hotspot2/omadm/ManagementTreeRoot.java
new file mode 100644
index 000000000..83a8dc834
--- /dev/null
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/ManagementTreeRoot.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 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.server.wifi.hotspot2.omadm;
+
+import java.util.Map;
+
+/**
+ * A specialized OMAConstructed OMA-DM node used as the MgmtTree root node in Passpoint
+ * management trees.
+ */
+public class ManagementTreeRoot extends OMAConstructed {
+ private final String mDtdRev;
+
+ public ManagementTreeRoot(XMLNode node, String dtdRev) {
+ super(null, MOTree.MgmtTreeTag, null, new MultiValueMap<OMANode>(),
+ node.getTextualAttributes());
+ mDtdRev = dtdRev;
+ }
+
+ public ManagementTreeRoot(String dtdRev) {
+ super(null, MOTree.MgmtTreeTag, null, "xmlns", OMAConstants.SyncML);
+ mDtdRev = dtdRev;
+ }
+
+ @Override
+ public void toXml(StringBuilder sb) {
+ sb.append('<').append(MOTree.MgmtTreeTag);
+ if (getAttributes() != null && !getAttributes().isEmpty()) {
+ for (Map.Entry<String, String> avp : getAttributes().entrySet()) {
+ sb.append(' ').append(avp.getKey()).append("=\"")
+ .append(escape(avp.getValue())).append('"');
+ }
+ }
+ sb.append(">\n");
+
+ sb.append('<').append(OMAConstants.SyncMLVersionTag)
+ .append('>').append(mDtdRev)
+ .append("</").append(OMAConstants.SyncMLVersionTag).append(">\n");
+ for (OMANode child : getChildren()) {
+ child.toXml(sb);
+ }
+ sb.append("</").append(MOTree.MgmtTreeTag).append(">\n");
+ }
+}
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/NodeAttribute.java b/service/java/com/android/server/wifi/hotspot2/omadm/NodeAttribute.java
index 1fc1adf7a..87ded86da 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/NodeAttribute.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/NodeAttribute.java
@@ -24,6 +24,19 @@ public class NodeAttribute {
}
@Override
+ public boolean equals(Object thatObject) {
+ if (this == thatObject) {
+ return true;
+ }
+ if (thatObject == null || getClass() != thatObject.getClass()) {
+ return false;
+ }
+
+ NodeAttribute that = (NodeAttribute) thatObject;
+ return mName.equals(that.mName) && mType.equals(that.mType) && mValue.equals(that.mValue);
+ }
+
+ @Override
public String toString() {
return String.format("%s (%s) = '%s'", mName, mType, mValue);
}
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/OMAConstructed.java b/service/java/com/android/server/wifi/hotspot2/omadm/OMAConstructed.java
index 10b159f5c..c0e4c66dd 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/OMAConstructed.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/OMAConstructed.java
@@ -15,7 +15,7 @@ public class OMAConstructed extends OMANode {
this(parent, name, context, new MultiValueMap<OMANode>(), buildAttributes(avps));
}
- private OMAConstructed(OMAConstructed parent, String name, String context,
+ protected OMAConstructed(OMAConstructed parent, String name, String context,
MultiValueMap<OMANode> children, Map<String, String> avps) {
super(parent, name, context, avps);
mChildren = children;
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/OMANode.java b/service/java/com/android/server/wifi/hotspot2/omadm/OMANode.java
index ff0c7e32e..fbb607561 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/OMANode.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/OMANode.java
@@ -16,6 +16,16 @@ public abstract class OMANode {
private final String mContext;
private final Map<String, String> mAttributes;
+ private static final Map<Character, String> sEscapes = new HashMap<>();
+
+ static {
+ sEscapes.put('"', "&quot;");
+ sEscapes.put('\'', "&apos;");
+ sEscapes.put('<', "&lt;");
+ sEscapes.put('>', "&gt;");
+ sEscapes.put('&', "&amp;");
+ }
+
protected OMANode(OMAConstructed parent, String name, String context, Map<String, String> avps) {
mParent = parent;
mName = name;
@@ -66,6 +76,25 @@ public abstract class OMANode {
return sb.toString();
}
+ /**
+ * Perform escaping of special XML characters
+ * @param s the raw string
+ * @return a "XML clean" representation
+ */
+ public static String escape(String s) {
+ StringBuilder sb = new StringBuilder(s.length());
+ for (int n = 0; n < s.length(); n++) {
+ char ch = s.charAt(n);
+ String escape = sEscapes.get(ch);
+ if (escape != null) {
+ sb.append(escape);
+ } else {
+ sb.append(ch);
+ }
+ }
+ return sb.toString();
+ }
+
public abstract OMANode reparent(OMAConstructed parent);
public abstract String getScalarValue(Iterator<String> path) throws OMAException;
@@ -93,7 +122,8 @@ public abstract class OMANode {
sb.append('<').append(MOTree.NodeTag);
if (mAttributes != null && !mAttributes.isEmpty()) {
for (Map.Entry<String, String> avp : mAttributes.entrySet()) {
- sb.append(' ').append(avp.getKey()).append("=\"").append(avp.getValue()).append('"');
+ sb.append(' ').append(avp.getKey()).append("=\"")
+ .append(escape(avp.getValue())).append('"');
}
}
sb.append(">\n");
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/OMAParser.java b/service/java/com/android/server/wifi/hotspot2/omadm/OMAParser.java
index 2669a302d..cbcd81d16 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/OMAParser.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/OMAParser.java
@@ -35,6 +35,10 @@ public class OMAParser extends DefaultHandler {
}
}
+ public XMLNode getRoot() {
+ return mRoot;
+ }
+
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/OMAScalar.java b/service/java/com/android/server/wifi/hotspot2/omadm/OMAScalar.java
index c8a3f9846..86740ac1c 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/OMAScalar.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/OMAScalar.java
@@ -1,7 +1,5 @@
package com.android.server.wifi.hotspot2.omadm;
-import android.util.Log;
-
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
@@ -83,7 +81,7 @@ public class OMAScalar extends OMANode {
@Override
public void fillPayload(StringBuilder sb) {
sb.append('<').append(MOTree.ValueTag).append('>');
- sb.append(mValue);
+ sb.append(escape(mValue));
sb.append("</").append(MOTree.ValueTag).append(">\n");
}
}
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/PasspointManagementObjectManager.java b/service/java/com/android/server/wifi/hotspot2/omadm/PasspointManagementObjectManager.java
index f26e83cbf..e967212e7 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/PasspointManagementObjectManager.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/PasspointManagementObjectManager.java
@@ -143,7 +143,7 @@ public class PasspointManagementObjectManager {
"unrestricted", UpdateInfo.UpdateRestriction.Unrestricted);
}
- private static void setSelections(String key, Object ... pairs) {
+ private static void setSelections(String key, Object... pairs) {
Map<String, Object> kvp = new HashMap<>();
sSelectionMap.put(key, kvp);
for (int n = 0; n < pairs.length; n += 2) {
@@ -161,10 +161,6 @@ public class PasspointManagementObjectManager {
mSPs = new HashMap<>();
}
- public File getPpsFile() {
- return mPpsFile;
- }
-
public boolean isEnabled() {
return mEnabled;
}
@@ -184,9 +180,11 @@ public class PasspointManagementObjectManager {
}
try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(mPpsFile))) {
- MOTree moTree = MOTree.unmarshal(in);
mSPs.clear();
- if (moTree == null) {
+ MOTree moTree;
+ try {
+ moTree = MOTree.unmarshal(in);
+ } catch (FileNotFoundException fnfe) {
return Collections.emptyList(); // Empty file
}
@@ -227,6 +225,7 @@ public class PasspointManagementObjectManager {
/**
* R1 *only* addSP method.
+ *
* @param homeSP
* @throws IOException
*/
@@ -282,6 +281,7 @@ public class PasspointManagementObjectManager {
/**
* Add an SP sub-tree. mo must be PPS with an immediate instance child (e.g. Cred01) and an
* optional UpdateIdentifier,
+ *
* @param mo The new MO
* @throws IOException
*/
@@ -306,7 +306,7 @@ public class PasspointManagementObjectManager {
if (instance != null) {
String nodeFqdn = getString(instance.getListValue(FQDNPath.iterator()));
if (fqdn.equalsIgnoreCase(nodeFqdn)) {
- return (OMAConstructed) node;
+ return (OMAConstructed) node;
// targetTree is rooted at the PPS
}
}
@@ -329,7 +329,7 @@ public class PasspointManagementObjectManager {
Log.d(Utils.hs2LogTag(getClass()), "modifying SP: " + mods);
MOTree moTree;
int ppsMods = 0;
- int updateIdentifier = 0;
+ int updateIdentifier;
try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(mPpsFile))) {
moTree = MOTree.unmarshal(in);
// moTree is PPS/?/provider-data
@@ -367,7 +367,7 @@ public class PasspointManagementObjectManager {
for (OMANode newNode : modRoot.getChildren()) {
// newNode is something like Credential
// current is the same existing node
- OMANode old = current.getParent().replaceNode(current, newNode);
+ current.getParent().replaceNode(current, newNode);
ppsMods++;
}
}
@@ -447,17 +447,8 @@ public class PasspointManagementObjectManager {
}
return MOTree.buildMgmtTree(OMAConstants.PPS_URN,
OMAConstants.OMAVersion, target).toXml();
- }
- }
-
- public MOTree getMOTree(HomeSP homeSP) throws IOException {
- try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(mPpsFile))) {
- MOTree moTree = MOTree.unmarshal(in);
- OMAConstructed target = findTargetTree(moTree, homeSP.getFQDN());
- if (target == null) {
- throw new IOException("Can't find " + homeSP.getFQDN() + " in MO tree");
- }
- return MOTree.buildMgmtTree(OMAConstants.PPS_URN, OMAConstants.OMAVersion, target);
+ } catch (FileNotFoundException fnfe) {
+ return null;
}
}
@@ -469,20 +460,6 @@ public class PasspointManagementObjectManager {
}
}
- private static String fqdnList(Collection<HomeSP> sps) {
- StringBuilder sb = new StringBuilder();
- boolean first = true;
- for (HomeSP sp : sps) {
- if (first) {
- first = false;
- } else {
- sb.append(", ");
- }
- sb.append(sp.getFQDN());
- }
- return sb.toString();
- }
-
private static OMANode buildHomeSPTree(HomeSP homeSP, OMAConstructed root, int instanceID)
throws IOException {
OMANode providerSubNode = root.addChild(getInstanceString(instanceID),
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/XMLNode.java b/service/java/com/android/server/wifi/hotspot2/omadm/XMLNode.java
index 3fa54a20a..76b7076df 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/XMLNode.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/XMLNode.java
@@ -9,6 +9,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -67,6 +68,46 @@ public class XMLNode {
mTextBuilder = new StringBuilder();
}
+ @Override
+ public boolean equals(Object thatObject) {
+ if (thatObject == this) {
+ return true;
+ } else if (thatObject.getClass() != XMLNode.class) {
+ return false;
+ }
+
+ XMLNode that = (XMLNode) thatObject;
+ if (!getTag().equals(that.getTag())
+ || mAttributes.size() != that.mAttributes.size()
+ || mChildren.size() != that.mChildren.size()) {
+ return false;
+ }
+
+ for (Map.Entry<String, NodeAttribute> entry : mAttributes.entrySet()) {
+ if (!entry.getValue().equals(that.mAttributes.get(entry.getKey()))) {
+ return false;
+ }
+ }
+
+ List<XMLNode> cloneOfThat = new ArrayList<>(that.mChildren);
+ for (XMLNode child : mChildren) {
+ Iterator<XMLNode> thatChildren = cloneOfThat.iterator();
+ boolean found = false;
+ while (thatChildren.hasNext()) {
+ XMLNode thatChild = thatChildren.next();
+ if (child.equals(thatChild)) {
+ found = true;
+ thatChildren.remove();
+ break;
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+ return true;
+ }
+
public void setText(String text) {
mText = text;
mTextBuilder = null;
@@ -152,6 +193,18 @@ public class XMLNode {
return Collections.unmodifiableMap(mAttributes);
}
+ /**
+ * Get the attributes of this node as a map of attribute name to attribute value.
+ * @return The attribute mapping.
+ */
+ public Map<String, String> getTextualAttributes() {
+ Map<String, String> map = new HashMap<>(mAttributes.size());
+ for (Map.Entry<String, NodeAttribute> entry : mAttributes.entrySet()) {
+ map.put(entry.getKey(), entry.getValue().getValue());
+ }
+ return map;
+ }
+
public String getAttributeValue(String name) {
NodeAttribute nodeAttribute = mAttributes.get(name);
return nodeAttribute != null ? nodeAttribute.getValue() : null;