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.support.test.filters.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        configuration.getOrCreateRandomizedMacAddress();
211
212        serializeDeserializeWifiConfigurationForConfigStore(configuration);
213    }
214
215    /**
216     * Verify that a WifiConfiguration with status as CURRENT when serializing
217     * is deserialized as ENABLED.
218     */
219    @Test
220    public void testCurrentStatusConfigurationSerializeDeserializeForConfigStore()
221            throws IOException, XmlPullParserException {
222        WifiConfiguration configuration = WifiConfigurationTestUtil.createEapNetwork();
223        configuration.status = WifiConfiguration.Status.CURRENT;
224        byte[] xmlData = serializeWifiConfigurationForConfigStore(configuration);
225        Pair<String, WifiConfiguration> deserializedConfiguration =
226                deserializeWifiConfiguration(xmlData);
227        assertEquals(WifiConfiguration.Status.ENABLED, deserializedConfiguration.second.status);
228    }
229
230    /**
231     * Verify that an enabled network selection status object is serialized & deserialized
232     * correctly.
233     */
234    @Test
235    public void testEnabledNetworkSelectionStatusSerializeDeserialize()
236            throws IOException, XmlPullParserException {
237        NetworkSelectionStatus status = new NetworkSelectionStatus();
238        status.setNetworkSelectionStatus(NetworkSelectionStatus.NETWORK_SELECTION_ENABLED);
239        status.setNetworkSelectionDisableReason(NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
240        status.setConnectChoice(TEST_DUMMY_CONFIG_KEY);
241        status.setConnectChoiceTimestamp(867889);
242        status.setHasEverConnected(true);
243        serializeDeserializeNetworkSelectionStatus(status);
244    }
245
246    /**
247     * Verify that a temporarily disabled network selection status object is serialized &
248     * deserialized correctly.
249     */
250    @Test
251    public void testTemporarilyDisabledNetworkSelectionStatusSerializeDeserialize()
252            throws IOException, XmlPullParserException {
253        NetworkSelectionStatus status = new NetworkSelectionStatus();
254        status.setNetworkSelectionStatus(
255                NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
256        status.setNetworkSelectionDisableReason(
257                NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION);
258        serializeDeserializeNetworkSelectionStatus(status);
259    }
260
261    /**
262     * Verify that a network selection status deprecation is handled correctly during restore
263     * of data after upgrade.
264     * This test tries to simulate the scenario where we have a
265     * {@link NetworkSelectionStatus#getNetworkStatusString()} string stored
266     * in the XML file from a previous release which has now been deprecated. The network should
267     * be restored as enabled.
268     */
269    @Test
270    public void testDeprecatedNetworkSelectionStatusDeserialize()
271            throws IOException, XmlPullParserException {
272        // Create a dummy network selection status.
273        NetworkSelectionStatus status = new NetworkSelectionStatus();
274        status.setNetworkSelectionStatus(
275                NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
276        status.setNetworkSelectionDisableReason(
277                NetworkSelectionStatus.DISABLED_DHCP_FAILURE);
278        status.setConnectChoice(TEST_DUMMY_CONFIG_KEY);
279        status.setConnectChoiceTimestamp(867889);
280        status.setHasEverConnected(true);
281
282        // Serialize this to XML string.
283        byte[] xmlData = serializeNetworkSelectionStatus(status);
284
285        // Now modify the status string with some invalid string in XML data..
286        String xmlString = new String(xmlData);
287        String deprecatedXmlString =
288                xmlString.replaceAll(
289                        status.getNetworkStatusString(), "NETWORK_SELECTION_DEPRECATED");
290        // Ensure that the modification did take effect.
291        assertFalse(xmlString.equals(deprecatedXmlString));
292
293        // Now Deserialize the modified XML data.
294        byte[] deprecatedXmlData = xmlString.getBytes();
295        NetworkSelectionStatus retrievedStatus =
296                deserializeNetworkSelectionStatus(deprecatedXmlData);
297
298        // The status retrieved should have reset both the |Status| & |DisableReason| fields after
299        // deserialization, but should have restored all the other fields correctly.
300        NetworkSelectionStatus expectedStatus = new NetworkSelectionStatus();
301        expectedStatus.copy(status);
302        expectedStatus.setNetworkSelectionStatus(NetworkSelectionStatus.NETWORK_SELECTION_ENABLED);
303        expectedStatus.setNetworkSelectionDisableReason(
304                NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
305
306        WifiConfigurationTestUtil.assertNetworkSelectionStatusEqualForConfigStore(
307                expectedStatus, retrievedStatus);
308    }
309
310    /**
311     * Verify that a network selection disable reason deprecation is handled correctly during
312     * restore of data after upgrade.
313     * This test tries to simulate the scenario where we have a
314     * {@link NetworkSelectionStatus#getNetworkDisableReasonString()} ()} string stored
315     * in the XML file from a previous release which has now been deprecated. The network should
316     * be restored as enabled.
317     */
318    @Test
319    public void testDeprecatedNetworkSelectionDisableReasonDeserialize()
320            throws IOException, XmlPullParserException {
321        // Create a dummy network selection status.
322        NetworkSelectionStatus status = new NetworkSelectionStatus();
323        status.setNetworkSelectionStatus(
324                NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
325        status.setNetworkSelectionDisableReason(
326                NetworkSelectionStatus.DISABLED_DHCP_FAILURE);
327        status.setConnectChoice(TEST_DUMMY_CONFIG_KEY);
328        status.setConnectChoiceTimestamp(867889);
329        status.setHasEverConnected(true);
330
331        // Serialize this to XML string.
332        byte[] xmlData = serializeNetworkSelectionStatus(status);
333
334        // Now modify the disable reason string with some invalid string in XML data.
335        String xmlString = new String(xmlData);
336        String deprecatedXmlString =
337                xmlString.replaceAll(status.getNetworkDisableReasonString(), "DISABLED_DEPRECATED");
338        // Ensure that the modification did take effect.
339        assertFalse(xmlString.equals(deprecatedXmlString));
340
341        // Now Deserialize the modified XML data.
342        byte[] deprecatedXmlData = xmlString.getBytes();
343        NetworkSelectionStatus retrievedStatus =
344                deserializeNetworkSelectionStatus(deprecatedXmlData);
345
346        // The status retrieved should have reset both the |Status| & |DisableReason| fields after
347        // deserialization, but should have restored all the other fields correctly.
348        NetworkSelectionStatus expectedStatus = new NetworkSelectionStatus();
349        expectedStatus.copy(status);
350        expectedStatus.setNetworkSelectionStatus(NetworkSelectionStatus.NETWORK_SELECTION_ENABLED);
351        expectedStatus.setNetworkSelectionDisableReason(
352                NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
353
354        WifiConfigurationTestUtil.assertNetworkSelectionStatusEqualForConfigStore(
355                expectedStatus, retrievedStatus);
356    }
357
358    /**
359     * Verify that a WifiEnterpriseConfig object is serialized & deserialized correctly.
360     */
361    @Test
362    public void testWifiEnterpriseConfigSerializeDeserialize()
363            throws IOException, XmlPullParserException {
364        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
365        config.setFieldValue(WifiEnterpriseConfig.IDENTITY_KEY, TEST_IDENTITY);
366        config.setFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY, TEST_ANON_IDENTITY);
367        config.setFieldValue(WifiEnterpriseConfig.PASSWORD_KEY, TEST_PASSWORD);
368        config.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, TEST_CLIENT_CERT);
369        config.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, TEST_CA_CERT);
370        config.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, TEST_SUBJECT_MATCH);
371        config.setFieldValue(WifiEnterpriseConfig.ENGINE_KEY, TEST_ENGINE);
372        config.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, TEST_ENGINE_ID);
373        config.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, TEST_PRIVATE_KEY_ID);
374        config.setFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, TEST_ALTSUBJECT_MATCH);
375        config.setFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, TEST_DOM_SUFFIX_MATCH);
376        config.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, TEST_CA_PATH);
377        config.setEapMethod(TEST_EAP_METHOD);
378        config.setPhase2Method(TEST_PHASE2_METHOD);
379        serializeDeserializeWifiEnterpriseConfig(config);
380    }
381
382    /**
383     * Verify that an illegal argument exception is thrown when trying to parse out a corrupted
384     * WifiEnterpriseConfig.
385     *
386     * @throws Exception
387     */
388    @Test(expected = IllegalArgumentException.class)
389    public void testWifiEnterpriseConfigSerializeDeserializeThrowsIllegalArgException()
390            throws Exception {
391        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
392        config.setFieldValue(WifiEnterpriseConfig.IDENTITY_KEY, TEST_IDENTITY);
393        config.setFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY, TEST_ANON_IDENTITY);
394        config.setFieldValue(WifiEnterpriseConfig.PASSWORD_KEY, TEST_PASSWORD);
395        config.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, TEST_CLIENT_CERT);
396        config.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, TEST_CA_CERT);
397        config.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, TEST_SUBJECT_MATCH);
398        config.setFieldValue(WifiEnterpriseConfig.ENGINE_KEY, TEST_ENGINE);
399        config.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, TEST_ENGINE_ID);
400        config.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, TEST_PRIVATE_KEY_ID);
401        config.setFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, TEST_ALTSUBJECT_MATCH);
402        config.setFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, TEST_DOM_SUFFIX_MATCH);
403        config.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, TEST_CA_PATH);
404        config.setEapMethod(TEST_EAP_METHOD);
405        config.setPhase2Method(TEST_PHASE2_METHOD);
406        String xmlString = new String(serializeWifiEnterpriseConfig(config));
407        // Manipulate the XML data to set the EAP method to None, this should raise an Illegal
408        // argument exception in WifiEnterpriseConfig.setEapMethod().
409        xmlString = xmlString.replaceAll(
410                String.format(XML_STRING_EAP_METHOD_REPLACE_FORMAT, TEST_EAP_METHOD),
411                String.format(XML_STRING_EAP_METHOD_REPLACE_FORMAT, WifiEnterpriseConfig.Eap.NONE));
412        deserializeWifiEnterpriseConfig(xmlString.getBytes(StandardCharsets.UTF_8));
413    }
414
415    /**
416     * Verify that WifiConfiguration representation of a legacy Passpoint configuration is
417     * serialized & deserialized correctly.
418     *
419     *@throws Exception
420     */
421    @Test
422    public void testLegacyPasspointConfigSerializeDeserialize() throws Exception {
423        WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork();
424        config.isLegacyPasspointConfig = true;
425        config.roamingConsortiumIds = new long[] {0x12345678};
426        config.enterpriseConfig.setPlmn("1234");
427        config.enterpriseConfig.setRealm("test.com");
428        serializeDeserializeWifiConfigurationForConfigStore(config);
429    }
430
431    private byte[] serializeWifiConfigurationForBackup(WifiConfiguration configuration)
432            throws IOException, XmlPullParserException {
433        final XmlSerializer out = new FastXmlSerializer();
434        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
435        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
436        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
437        WifiConfigurationXmlUtil.writeToXmlForBackup(out, configuration);
438        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
439        return outputStream.toByteArray();
440    }
441
442    private byte[] serializeWifiConfigurationForConfigStore(
443            WifiConfiguration configuration)
444            throws IOException, XmlPullParserException {
445        final XmlSerializer out = new FastXmlSerializer();
446        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
447        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
448        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
449        WifiConfigurationXmlUtil.writeToXmlForConfigStore(out, configuration);
450        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
451        return outputStream.toByteArray();
452    }
453
454    private Pair<String, WifiConfiguration> deserializeWifiConfiguration(byte[] data)
455            throws IOException, XmlPullParserException {
456        // Deserialize the configuration object.
457        final XmlPullParser in = Xml.newPullParser();
458        ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
459        in.setInput(inputStream, StandardCharsets.UTF_8.name());
460        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
461        return WifiConfigurationXmlUtil.parseFromXml(in, in.getDepth());
462    }
463
464    /**
465     * This helper method tests the serialization for backup/restore.
466     */
467    private void serializeDeserializeWifiConfigurationForBackupRestore(
468            WifiConfiguration configuration)
469            throws IOException, XmlPullParserException {
470        Pair<String, WifiConfiguration> retrieved;
471        // Test serialization/deserialization for config store.
472        retrieved =
473                deserializeWifiConfiguration(
474                        serializeWifiConfigurationForBackup(configuration));
475        assertEquals(retrieved.first, retrieved.second.configKey());
476        WifiConfigurationTestUtil.assertConfigurationEqualForBackup(
477                configuration, retrieved.second);
478    }
479
480    /**
481     * This helper method tests the serialization for config store.
482     */
483    private void serializeDeserializeWifiConfigurationForConfigStore(
484            WifiConfiguration configuration)
485            throws IOException, XmlPullParserException {
486        // Reset enterprise config because this needs to be serialized/deserialized separately.
487        configuration.enterpriseConfig = new WifiEnterpriseConfig();
488        Pair<String, WifiConfiguration> retrieved;
489        // Test serialization/deserialization for config store.
490        retrieved =
491                deserializeWifiConfiguration(
492                        serializeWifiConfigurationForConfigStore(configuration));
493        assertEquals(retrieved.first, retrieved.second.configKey());
494        WifiConfigurationTestUtil.assertConfigurationEqualForConfigStore(
495                configuration, retrieved.second);
496    }
497
498    /**
499     * This helper method tests both the serialization for backup/restore and config store.
500     */
501    private void serializeDeserializeWifiConfiguration(WifiConfiguration configuration)
502            throws IOException, XmlPullParserException {
503        Pair<String, WifiConfiguration> retrieved;
504        // Test serialization/deserialization for backup first.
505        serializeDeserializeWifiConfigurationForBackupRestore(configuration);
506
507        // Test serialization/deserialization for config store.
508        serializeDeserializeWifiConfigurationForConfigStore(configuration);
509    }
510
511    private void serializeDeserializeIpConfiguration(IpConfiguration configuration)
512            throws IOException, XmlPullParserException {
513        // Serialize the configuration object.
514        final XmlSerializer out = new FastXmlSerializer();
515        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
516        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
517        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
518        IpConfigurationXmlUtil.writeToXml(out, configuration);
519        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
520
521        // Deserialize the configuration object.
522        final XmlPullParser in = Xml.newPullParser();
523        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
524        in.setInput(inputStream, StandardCharsets.UTF_8.name());
525        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
526        IpConfiguration retrievedConfiguration =
527                IpConfigurationXmlUtil.parseFromXml(in, in.getDepth());
528        assertEquals(configuration, retrievedConfiguration);
529    }
530
531    private byte[] serializeNetworkSelectionStatus(NetworkSelectionStatus status)
532            throws IOException, XmlPullParserException {
533        // Serialize the configuration object.
534        final XmlSerializer out = new FastXmlSerializer();
535        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
536        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
537        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
538        NetworkSelectionStatusXmlUtil.writeToXml(out, status);
539        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
540        return outputStream.toByteArray();
541    }
542
543    private NetworkSelectionStatus deserializeNetworkSelectionStatus(byte[] data)
544            throws IOException, XmlPullParserException {
545        final XmlPullParser in = Xml.newPullParser();
546        ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
547        in.setInput(inputStream, StandardCharsets.UTF_8.name());
548        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
549        return NetworkSelectionStatusXmlUtil.parseFromXml(in, in.getDepth());
550    }
551
552    private void serializeDeserializeNetworkSelectionStatus(NetworkSelectionStatus status)
553            throws IOException, XmlPullParserException {
554        // Serialize the status object.
555        byte[] data = serializeNetworkSelectionStatus(status);
556        // Deserialize the status object.
557        NetworkSelectionStatus retrievedStatus = deserializeNetworkSelectionStatus(data);
558
559        WifiConfigurationTestUtil.assertNetworkSelectionStatusEqualForConfigStore(
560                status, retrievedStatus);
561    }
562
563    private byte[] serializeWifiEnterpriseConfig(WifiEnterpriseConfig config)
564            throws IOException, XmlPullParserException {
565        final XmlSerializer out = new FastXmlSerializer();
566        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
567        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
568        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
569        WifiEnterpriseConfigXmlUtil.writeToXml(out, config);
570        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
571        return outputStream.toByteArray();
572    }
573
574    private WifiEnterpriseConfig deserializeWifiEnterpriseConfig(byte[] data)
575            throws IOException, XmlPullParserException {
576        final XmlPullParser in = Xml.newPullParser();
577        ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
578        in.setInput(inputStream, StandardCharsets.UTF_8.name());
579        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
580        return WifiEnterpriseConfigXmlUtil.parseFromXml(in, in.getDepth());
581    }
582
583    private void serializeDeserializeWifiEnterpriseConfig(WifiEnterpriseConfig config)
584            throws IOException, XmlPullParserException {
585        WifiEnterpriseConfig retrievedConfig =
586                deserializeWifiEnterpriseConfig(serializeWifiEnterpriseConfig(config));
587        WifiConfigurationTestUtil.assertWifiEnterpriseConfigEqualForConfigStore(
588                config, retrievedConfig);
589    }
590}
591