1/*
2 * Copyright (C) 2016 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
17package com.android.server.wifi.util;
18
19import static org.junit.Assert.*;
20import static org.mockito.Mockito.*;
21
22import android.net.IpConfiguration;
23import android.net.wifi.WifiConfiguration;
24import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
25import android.net.wifi.WifiEnterpriseConfig;
26import android.test.suitebuilder.annotation.SmallTest;
27import android.util.Pair;
28import android.util.Xml;
29
30import com.android.internal.util.FastXmlSerializer;
31import com.android.server.wifi.WifiConfigurationTestUtil;
32import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
33import com.android.server.wifi.util.XmlUtil.NetworkSelectionStatusXmlUtil;
34import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
35import com.android.server.wifi.util.XmlUtil.WifiEnterpriseConfigXmlUtil;
36
37import org.junit.Test;
38import org.xmlpull.v1.XmlPullParser;
39import org.xmlpull.v1.XmlPullParserException;
40import org.xmlpull.v1.XmlSerializer;
41
42import java.io.ByteArrayInputStream;
43import java.io.ByteArrayOutputStream;
44import java.io.IOException;
45import java.nio.charset.StandardCharsets;
46import java.util.HashMap;
47
48/**
49 * Unit tests for {@link com.android.server.wifi.util.XmlUtil}.
50 */
51@SmallTest
52public class XmlUtilTest {
53    public static final String XML_STRING_EAP_METHOD_REPLACE_FORMAT =
54            "<int name=\"EapMethod\" value=\"%d\" />";
55
56    private static final String TEST_PACKAGE_NAME = "XmlUtilPackage";
57    private static final String TEST_STATIC_IP_GATEWAY_ADDRESS = "192.168.48.1";
58    private static final String TEST_DUMMY_CONFIG_KEY = "XmlUtilDummyConfigKey";
59    private static final String TEST_IDENTITY = "XmlUtilTestIdentity";
60    private static final String TEST_ANON_IDENTITY = "XmlUtilTestAnonIdentity";
61    private static final String TEST_PASSWORD = "XmlUtilTestPassword";
62    private static final String TEST_CLIENT_CERT = "XmlUtilTestClientCert";
63    private static final String TEST_CA_CERT = "XmlUtilTestCaCert";
64    private static final String TEST_SUBJECT_MATCH = "XmlUtilTestSubjectMatch";
65    private static final String TEST_ENGINE = "XmlUtilTestEngine";
66    private static final String TEST_ENGINE_ID = "XmlUtilTestEngineId";
67    private static final String TEST_PRIVATE_KEY_ID = "XmlUtilTestPrivateKeyId";
68    private static final String TEST_ALTSUBJECT_MATCH = "XmlUtilTestAltSubjectMatch";
69    private static final String TEST_DOM_SUFFIX_MATCH = "XmlUtilTestDomSuffixMatch";
70    private static final String TEST_CA_PATH = "XmlUtilTestCaPath";
71    private static final int TEST_EAP_METHOD = WifiEnterpriseConfig.Eap.PEAP;
72    private static final int TEST_PHASE2_METHOD = WifiEnterpriseConfig.Phase2.MSCHAPV2;
73    private final String mXmlDocHeader = "XmlUtilTest";
74
75    /**
76     * Verify that a open WifiConfiguration is serialized & deserialized correctly.
77     */
78    @Test
79    public void testOpenWifiConfigurationSerializeDeserialize()
80            throws IOException, XmlPullParserException {
81        serializeDeserializeWifiConfiguration(WifiConfigurationTestUtil.createOpenNetwork());
82    }
83
84    /**
85     * Verify that a open hidden WifiConfiguration is serialized & deserialized correctly.
86     */
87    @Test
88    public void testOpenHiddenWifiConfigurationSerializeDeserialize()
89            throws IOException, XmlPullParserException {
90        serializeDeserializeWifiConfiguration(WifiConfigurationTestUtil.createOpenHiddenNetwork());
91    }
92
93    /**
94     * Verify that a psk WifiConfiguration is serialized & deserialized correctly.
95     */
96    @Test
97    public void testPskWifiConfigurationSerializeDeserialize()
98            throws IOException, XmlPullParserException {
99        serializeDeserializeWifiConfiguration(WifiConfigurationTestUtil.createPskNetwork());
100    }
101
102    /**
103     * Verify that a psk hidden WifiConfiguration is serialized & deserialized correctly.
104     */
105    @Test
106    public void testPskHiddenWifiConfigurationSerializeDeserialize()
107            throws IOException, XmlPullParserException {
108        serializeDeserializeWifiConfiguration(WifiConfigurationTestUtil.createPskHiddenNetwork());
109    }
110
111    /**
112     * Verify that a WEP WifiConfiguration is serialized & deserialized correctly.
113     */
114    @Test
115    public void testWepWifiConfigurationSerializeDeserialize()
116            throws IOException, XmlPullParserException {
117        serializeDeserializeWifiConfiguration(WifiConfigurationTestUtil.createWepNetwork());
118    }
119
120    /**
121     * Verify that a EAP WifiConfiguration is serialized & deserialized correctly only for
122     * ConfigStore.
123     */
124    @Test
125    public void testEapWifiConfigurationSerializeDeserialize()
126            throws IOException, XmlPullParserException {
127        serializeDeserializeWifiConfigurationForConfigStore(
128                WifiConfigurationTestUtil.createEapNetwork());
129    }
130
131    /**
132     * Verify that a static IpConfiguration with PAC proxy is serialized & deserialized correctly.
133     */
134    @Test
135    public void testStaticIpConfigurationWithPacProxySerializeDeserialize()
136            throws IOException, XmlPullParserException {
137        serializeDeserializeIpConfiguration(
138                WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
139    }
140
141    /**
142     * Verify that a static IpConfiguration with static proxy is serialized & deserialized correctly.
143     */
144    @Test
145    public void testStaticIpConfigurationWithStaticProxySerializeDeserialize()
146            throws IOException, XmlPullParserException {
147        serializeDeserializeIpConfiguration(
148                WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy());
149    }
150
151    /**
152     * Verify that a partial static IpConfiguration with PAC proxy is serialized & deserialized
153     * correctly.
154     */
155    @Test
156    public void testPartialStaticIpConfigurationWithPacProxySerializeDeserialize()
157            throws IOException, XmlPullParserException {
158        serializeDeserializeIpConfiguration(
159                WifiConfigurationTestUtil.createPartialStaticIpConfigurationWithPacProxy());
160    }
161
162    /**
163     * Verify that a DHCP IpConfiguration with PAC proxy is serialized & deserialized
164     * correctly.
165     */
166    @Test
167    public void testDHCPIpConfigurationWithPacProxySerializeDeserialize()
168            throws IOException, XmlPullParserException {
169        serializeDeserializeIpConfiguration(
170                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy());
171    }
172
173    /**
174     * Verify that a DHCP IpConfiguration with Static proxy is serialized & deserialized
175     * correctly.
176     */
177    @Test
178    public void testDHCPIpConfigurationWithStaticProxySerializeDeserialize()
179            throws IOException, XmlPullParserException {
180        serializeDeserializeIpConfiguration(
181                WifiConfigurationTestUtil.createDHCPIpConfigurationWithStaticProxy());
182    }
183
184    /**
185     * Verify that a EAP WifiConfiguration is serialized & deserialized correctly for config store.
186     * This basically exercises all the elements being serialized in config store.
187     */
188    @Test
189    public void testEapWifiConfigurationSerializeDeserializeForConfigStore()
190            throws IOException, XmlPullParserException {
191        WifiConfiguration configuration = WifiConfigurationTestUtil.createEapNetwork();
192        configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
193        configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
194        configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
195        configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
196        configuration.status = WifiConfiguration.Status.DISABLED;
197        configuration.linkedConfigurations = new HashMap<>();
198        configuration.linkedConfigurations.put(TEST_DUMMY_CONFIG_KEY, Integer.valueOf(1));
199        configuration.defaultGwMacAddress = TEST_STATIC_IP_GATEWAY_ADDRESS;
200        configuration.requirePMF = true;
201        configuration.validatedInternetAccess = true;
202        configuration.noInternetAccessExpected = true;
203        configuration.userApproved = WifiConfiguration.USER_UNSPECIFIED;
204        configuration.meteredHint = true;
205        configuration.useExternalScores = true;
206        configuration.numAssociation = 5;
207        configuration.lastUpdateUid = configuration.lastConnectUid = configuration.creatorUid;
208        configuration.creatorName = configuration.lastUpdateName = TEST_PACKAGE_NAME;
209        configuration.creationTime = "04-04-2016";
210
211        serializeDeserializeWifiConfigurationForConfigStore(configuration);
212    }
213
214    /**
215     * Verify that a WifiConfiguration with status as CURRENT when serializing
216     * is deserialized as ENABLED.
217     */
218    @Test
219    public void testCurrentStatusConfigurationSerializeDeserializeForConfigStore()
220            throws IOException, XmlPullParserException {
221        WifiConfiguration configuration = WifiConfigurationTestUtil.createEapNetwork();
222        configuration.status = WifiConfiguration.Status.CURRENT;
223        byte[] xmlData = serializeWifiConfigurationForConfigStore(configuration);
224        Pair<String, WifiConfiguration> deserializedConfiguration =
225                deserializeWifiConfiguration(xmlData);
226        assertEquals(WifiConfiguration.Status.ENABLED, deserializedConfiguration.second.status);
227    }
228
229    /**
230     * Verify that an enabled network selection status object is serialized & deserialized
231     * correctly.
232     */
233    @Test
234    public void testEnabledNetworkSelectionStatusSerializeDeserialize()
235            throws IOException, XmlPullParserException {
236        NetworkSelectionStatus status = new NetworkSelectionStatus();
237        status.setNetworkSelectionStatus(NetworkSelectionStatus.NETWORK_SELECTION_ENABLED);
238        status.setNetworkSelectionDisableReason(NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
239        status.setConnectChoice(TEST_DUMMY_CONFIG_KEY);
240        status.setConnectChoiceTimestamp(867889);
241        status.setHasEverConnected(true);
242        serializeDeserializeNetworkSelectionStatus(status);
243    }
244
245    /**
246     * Verify that a temporarily disabled network selection status object is serialized &
247     * deserialized correctly.
248     */
249    @Test
250    public void testTemporarilyDisabledNetworkSelectionStatusSerializeDeserialize()
251            throws IOException, XmlPullParserException {
252        NetworkSelectionStatus status = new NetworkSelectionStatus();
253        status.setNetworkSelectionStatus(
254                NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
255        status.setNetworkSelectionDisableReason(
256                NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION);
257        serializeDeserializeNetworkSelectionStatus(status);
258    }
259
260    /**
261     * Verify that a network selection status deprecation is handled correctly during restore
262     * of data after upgrade.
263     * This test tries to simulate the scenario where we have a
264     * {@link NetworkSelectionStatus#getNetworkStatusString()} string stored
265     * in the XML file from a previous release which has now been deprecated. The network should
266     * be restored as enabled.
267     */
268    @Test
269    public void testDeprecatedNetworkSelectionStatusDeserialize()
270            throws IOException, XmlPullParserException {
271        // Create a dummy network selection status.
272        NetworkSelectionStatus status = new NetworkSelectionStatus();
273        status.setNetworkSelectionStatus(
274                NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
275        status.setNetworkSelectionDisableReason(
276                NetworkSelectionStatus.DISABLED_DHCP_FAILURE);
277        status.setConnectChoice(TEST_DUMMY_CONFIG_KEY);
278        status.setConnectChoiceTimestamp(867889);
279        status.setHasEverConnected(true);
280
281        // Serialize this to XML string.
282        byte[] xmlData = serializeNetworkSelectionStatus(status);
283
284        // Now modify the status string with some invalid string in XML data..
285        String xmlString = new String(xmlData);
286        String deprecatedXmlString =
287                xmlString.replaceAll(
288                        status.getNetworkStatusString(), "NETWORK_SELECTION_DEPRECATED");
289        // Ensure that the modification did take effect.
290        assertFalse(xmlString.equals(deprecatedXmlString));
291
292        // Now Deserialize the modified XML data.
293        byte[] deprecatedXmlData = xmlString.getBytes();
294        NetworkSelectionStatus retrievedStatus =
295                deserializeNetworkSelectionStatus(deprecatedXmlData);
296
297        // The status retrieved should have reset both the |Status| & |DisableReason| fields after
298        // deserialization, but should have restored all the other fields correctly.
299        NetworkSelectionStatus expectedStatus = new NetworkSelectionStatus();
300        expectedStatus.copy(status);
301        expectedStatus.setNetworkSelectionStatus(NetworkSelectionStatus.NETWORK_SELECTION_ENABLED);
302        expectedStatus.setNetworkSelectionDisableReason(
303                NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
304
305        WifiConfigurationTestUtil.assertNetworkSelectionStatusEqualForConfigStore(
306                expectedStatus, retrievedStatus);
307    }
308
309    /**
310     * Verify that a network selection disable reason deprecation is handled correctly during
311     * restore of data after upgrade.
312     * This test tries to simulate the scenario where we have a
313     * {@link NetworkSelectionStatus#getNetworkDisableReasonString()} ()} string stored
314     * in the XML file from a previous release which has now been deprecated. The network should
315     * be restored as enabled.
316     */
317    @Test
318    public void testDeprecatedNetworkSelectionDisableReasonDeserialize()
319            throws IOException, XmlPullParserException {
320        // Create a dummy network selection status.
321        NetworkSelectionStatus status = new NetworkSelectionStatus();
322        status.setNetworkSelectionStatus(
323                NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
324        status.setNetworkSelectionDisableReason(
325                NetworkSelectionStatus.DISABLED_DHCP_FAILURE);
326        status.setConnectChoice(TEST_DUMMY_CONFIG_KEY);
327        status.setConnectChoiceTimestamp(867889);
328        status.setHasEverConnected(true);
329
330        // Serialize this to XML string.
331        byte[] xmlData = serializeNetworkSelectionStatus(status);
332
333        // Now modify the disable reason string with some invalid string in XML data.
334        String xmlString = new String(xmlData);
335        String deprecatedXmlString =
336                xmlString.replaceAll(status.getNetworkDisableReasonString(), "DISABLED_DEPRECATED");
337        // Ensure that the modification did take effect.
338        assertFalse(xmlString.equals(deprecatedXmlString));
339
340        // Now Deserialize the modified XML data.
341        byte[] deprecatedXmlData = xmlString.getBytes();
342        NetworkSelectionStatus retrievedStatus =
343                deserializeNetworkSelectionStatus(deprecatedXmlData);
344
345        // The status retrieved should have reset both the |Status| & |DisableReason| fields after
346        // deserialization, but should have restored all the other fields correctly.
347        NetworkSelectionStatus expectedStatus = new NetworkSelectionStatus();
348        expectedStatus.copy(status);
349        expectedStatus.setNetworkSelectionStatus(NetworkSelectionStatus.NETWORK_SELECTION_ENABLED);
350        expectedStatus.setNetworkSelectionDisableReason(
351                NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
352
353        WifiConfigurationTestUtil.assertNetworkSelectionStatusEqualForConfigStore(
354                expectedStatus, retrievedStatus);
355    }
356
357    /**
358     * Verify that a WifiEnterpriseConfig object is serialized & deserialized correctly.
359     */
360    @Test
361    public void testWifiEnterpriseConfigSerializeDeserialize()
362            throws IOException, XmlPullParserException {
363        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
364        config.setFieldValue(WifiEnterpriseConfig.IDENTITY_KEY, TEST_IDENTITY);
365        config.setFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY, TEST_ANON_IDENTITY);
366        config.setFieldValue(WifiEnterpriseConfig.PASSWORD_KEY, TEST_PASSWORD);
367        config.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, TEST_CLIENT_CERT);
368        config.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, TEST_CA_CERT);
369        config.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, TEST_SUBJECT_MATCH);
370        config.setFieldValue(WifiEnterpriseConfig.ENGINE_KEY, TEST_ENGINE);
371        config.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, TEST_ENGINE_ID);
372        config.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, TEST_PRIVATE_KEY_ID);
373        config.setFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, TEST_ALTSUBJECT_MATCH);
374        config.setFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, TEST_DOM_SUFFIX_MATCH);
375        config.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, TEST_CA_PATH);
376        config.setEapMethod(TEST_EAP_METHOD);
377        config.setPhase2Method(TEST_PHASE2_METHOD);
378        serializeDeserializeWifiEnterpriseConfig(config);
379    }
380
381    /**
382     * Verify that an illegal argument exception is thrown when trying to parse out a corrupted
383     * WifiEnterpriseConfig.
384     *
385     * @throws Exception
386     */
387    @Test(expected = IllegalArgumentException.class)
388    public void testWifiEnterpriseConfigSerializeDeserializeThrowsIllegalArgException()
389            throws Exception {
390        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
391        config.setFieldValue(WifiEnterpriseConfig.IDENTITY_KEY, TEST_IDENTITY);
392        config.setFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY, TEST_ANON_IDENTITY);
393        config.setFieldValue(WifiEnterpriseConfig.PASSWORD_KEY, TEST_PASSWORD);
394        config.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, TEST_CLIENT_CERT);
395        config.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, TEST_CA_CERT);
396        config.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, TEST_SUBJECT_MATCH);
397        config.setFieldValue(WifiEnterpriseConfig.ENGINE_KEY, TEST_ENGINE);
398        config.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, TEST_ENGINE_ID);
399        config.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, TEST_PRIVATE_KEY_ID);
400        config.setFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, TEST_ALTSUBJECT_MATCH);
401        config.setFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, TEST_DOM_SUFFIX_MATCH);
402        config.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, TEST_CA_PATH);
403        config.setEapMethod(TEST_EAP_METHOD);
404        config.setPhase2Method(TEST_PHASE2_METHOD);
405        String xmlString = new String(serializeWifiEnterpriseConfig(config));
406        // Manipulate the XML data to set the EAP method to None, this should raise an Illegal
407        // argument exception in WifiEnterpriseConfig.setEapMethod().
408        xmlString = xmlString.replaceAll(
409                String.format(XML_STRING_EAP_METHOD_REPLACE_FORMAT, TEST_EAP_METHOD),
410                String.format(XML_STRING_EAP_METHOD_REPLACE_FORMAT, WifiEnterpriseConfig.Eap.NONE));
411        deserializeWifiEnterpriseConfig(xmlString.getBytes(StandardCharsets.UTF_8));
412    }
413
414    /**
415     * Verify that WifiConfiguration representation of a legacy Passpoint configuration is
416     * serialized & deserialized correctly.
417     *
418     *@throws Exception
419     */
420    @Test
421    public void testLegacyPasspointConfigSerializeDeserialize() throws Exception {
422        WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork();
423        config.isLegacyPasspointConfig = true;
424        config.roamingConsortiumIds = new long[] {0x12345678};
425        config.enterpriseConfig.setPlmn("1234");
426        config.enterpriseConfig.setRealm("test.com");
427        serializeDeserializeWifiConfigurationForConfigStore(config);
428    }
429
430    private byte[] serializeWifiConfigurationForBackup(WifiConfiguration configuration)
431            throws IOException, XmlPullParserException {
432        final XmlSerializer out = new FastXmlSerializer();
433        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
434        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
435        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
436        WifiConfigurationXmlUtil.writeToXmlForBackup(out, configuration);
437        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
438        return outputStream.toByteArray();
439    }
440
441    private byte[] serializeWifiConfigurationForConfigStore(
442            WifiConfiguration configuration)
443            throws IOException, XmlPullParserException {
444        final XmlSerializer out = new FastXmlSerializer();
445        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
446        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
447        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
448        WifiConfigurationXmlUtil.writeToXmlForConfigStore(out, configuration);
449        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
450        return outputStream.toByteArray();
451    }
452
453    private Pair<String, WifiConfiguration> deserializeWifiConfiguration(byte[] data)
454            throws IOException, XmlPullParserException {
455        // Deserialize the configuration object.
456        final XmlPullParser in = Xml.newPullParser();
457        ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
458        in.setInput(inputStream, StandardCharsets.UTF_8.name());
459        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
460        return WifiConfigurationXmlUtil.parseFromXml(in, in.getDepth());
461    }
462
463    /**
464     * This helper method tests the serialization for backup/restore.
465     */
466    private void serializeDeserializeWifiConfigurationForBackupRestore(
467            WifiConfiguration configuration)
468            throws IOException, XmlPullParserException {
469        Pair<String, WifiConfiguration> retrieved;
470        // Test serialization/deserialization for config store.
471        retrieved =
472                deserializeWifiConfiguration(
473                        serializeWifiConfigurationForBackup(configuration));
474        assertEquals(retrieved.first, retrieved.second.configKey());
475        WifiConfigurationTestUtil.assertConfigurationEqualForBackup(
476                configuration, retrieved.second);
477    }
478
479    /**
480     * This helper method tests the serialization for config store.
481     */
482    private void serializeDeserializeWifiConfigurationForConfigStore(
483            WifiConfiguration configuration)
484            throws IOException, XmlPullParserException {
485        // Reset enterprise config because this needs to be serialized/deserialized separately.
486        configuration.enterpriseConfig = new WifiEnterpriseConfig();
487        Pair<String, WifiConfiguration> retrieved;
488        // Test serialization/deserialization for config store.
489        retrieved =
490                deserializeWifiConfiguration(
491                        serializeWifiConfigurationForConfigStore(configuration));
492        assertEquals(retrieved.first, retrieved.second.configKey());
493        WifiConfigurationTestUtil.assertConfigurationEqualForConfigStore(
494                configuration, retrieved.second);
495    }
496
497    /**
498     * This helper method tests both the serialization for backup/restore and config store.
499     */
500    private void serializeDeserializeWifiConfiguration(WifiConfiguration configuration)
501            throws IOException, XmlPullParserException {
502        Pair<String, WifiConfiguration> retrieved;
503        // Test serialization/deserialization for backup first.
504        serializeDeserializeWifiConfigurationForBackupRestore(configuration);
505
506        // Test serialization/deserialization for config store.
507        serializeDeserializeWifiConfigurationForConfigStore(configuration);
508    }
509
510    private void serializeDeserializeIpConfiguration(IpConfiguration configuration)
511            throws IOException, XmlPullParserException {
512        // Serialize the configuration object.
513        final XmlSerializer out = new FastXmlSerializer();
514        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
515        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
516        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
517        IpConfigurationXmlUtil.writeToXml(out, configuration);
518        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
519
520        // Deserialize the configuration object.
521        final XmlPullParser in = Xml.newPullParser();
522        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
523        in.setInput(inputStream, StandardCharsets.UTF_8.name());
524        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
525        IpConfiguration retrievedConfiguration =
526                IpConfigurationXmlUtil.parseFromXml(in, in.getDepth());
527        assertEquals(configuration, retrievedConfiguration);
528    }
529
530    private byte[] serializeNetworkSelectionStatus(NetworkSelectionStatus status)
531            throws IOException, XmlPullParserException {
532        // Serialize the configuration object.
533        final XmlSerializer out = new FastXmlSerializer();
534        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
535        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
536        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
537        NetworkSelectionStatusXmlUtil.writeToXml(out, status);
538        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
539        return outputStream.toByteArray();
540    }
541
542    private NetworkSelectionStatus deserializeNetworkSelectionStatus(byte[] data)
543            throws IOException, XmlPullParserException {
544        final XmlPullParser in = Xml.newPullParser();
545        ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
546        in.setInput(inputStream, StandardCharsets.UTF_8.name());
547        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
548        return NetworkSelectionStatusXmlUtil.parseFromXml(in, in.getDepth());
549    }
550
551    private void serializeDeserializeNetworkSelectionStatus(NetworkSelectionStatus status)
552            throws IOException, XmlPullParserException {
553        // Serialize the status object.
554        byte[] data = serializeNetworkSelectionStatus(status);
555        // Deserialize the status object.
556        NetworkSelectionStatus retrievedStatus = deserializeNetworkSelectionStatus(data);
557
558        WifiConfigurationTestUtil.assertNetworkSelectionStatusEqualForConfigStore(
559                status, retrievedStatus);
560    }
561
562    private byte[] serializeWifiEnterpriseConfig(WifiEnterpriseConfig config)
563            throws IOException, XmlPullParserException {
564        final XmlSerializer out = new FastXmlSerializer();
565        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
566        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
567        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
568        WifiEnterpriseConfigXmlUtil.writeToXml(out, config);
569        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
570        return outputStream.toByteArray();
571    }
572
573    private WifiEnterpriseConfig deserializeWifiEnterpriseConfig(byte[] data)
574            throws IOException, XmlPullParserException {
575        final XmlPullParser in = Xml.newPullParser();
576        ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
577        in.setInput(inputStream, StandardCharsets.UTF_8.name());
578        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
579        return WifiEnterpriseConfigXmlUtil.parseFromXml(in, in.getDepth());
580    }
581
582    private void serializeDeserializeWifiEnterpriseConfig(WifiEnterpriseConfig config)
583            throws IOException, XmlPullParserException {
584        WifiEnterpriseConfig retrievedConfig =
585                deserializeWifiEnterpriseConfig(serializeWifiEnterpriseConfig(config));
586        WifiConfigurationTestUtil.assertWifiEnterpriseConfigEqualForConfigStore(
587                config, retrievedConfig);
588    }
589}
590