Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44bcb759 authored by Peter Qiu's avatar Peter Qiu Committed by android-build-merger
Browse files

hotspot2: added remaining parameters to PasspointConfiguration

am: ddf6fa06

Change-Id: I023acc0ae2920391de8a8de8ee95152f510ca9bd
parents 01e738a0 ddf6fa06
Loading
Loading
Loading
Loading
+262 −13
Original line number Diff line number Diff line
@@ -19,9 +19,18 @@ package android.net.wifi.hotspot2;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSP;
import android.net.wifi.hotspot2.pps.Policy;
import android.net.wifi.hotspot2.pps.UpdateParameter;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import android.os.Parcel;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Class representing Passpoint configuration.  This contains configurations specified in
 * PerProviderSubscription (PPS) Management Object (MO) tree.
@@ -32,10 +41,106 @@ import android.os.Parcel;
 * @hide
 */
public final class PasspointConfiguration implements Parcelable {
    private static final String TAG = "PasspointConfiguration";

    /**
     * Number of bytes for certificate SHA-256 fingerprint byte array.
     */
    private static final int CERTIFICATE_SHA256_BYTES = 32;

    /**
     * Maximum bytes for URL string.
     */
    private static final int MAX_URL_BYTES = 1023;

    /**
     * Integer value used for indicating null value in the Parcel.
     */
    private static final int NULL_VALUE = -1;

    public HomeSP homeSp = null;
    public Credential credential = null;
    public Policy policy = null;

    /**
     * Meta data for performing subscription update.
     */
    public UpdateParameter subscriptionUpdate = null;

    /**
     * List of HTTPS URL for retrieving trust root certificate and the corresponding SHA-256
     * fingerprint of the certificate.  The certificates are used for verifying AAA server's
     * identity during EAP authentication.
     */
    public Map<String, byte[]> trustRootCertList = null;

    /**
     * Set by the subscription server, updated every time the configuration is updated by
     * the subscription server.
     *
     * Use Integer.MIN_VALUE to indicate unset value.
     */
    public int updateIdentifier = Integer.MIN_VALUE;

    /**
     * The priority of the credential.
     *
     * Use Integer.MIN_VALUE to indicate unset value.
     */
    public int credentialPriority = Integer.MIN_VALUE;

    /**
     * The time this subscription is created. It is in the format of number
     * of milliseconds since January 1, 1970, 00:00:00 GMT.
     *
     * Use Long.MIN_VALUE to indicate unset value.
     */
    public long subscriptionCreationTimeInMs = Long.MIN_VALUE;

    /**
     * The time this subscription will expire. It is in the format of number
     * of milliseconds since January 1, 1970, 00:00:00 GMT.
     *
     * Use Long.MIN_VALUE to indicate unset value.
     */
    public long subscriptionExpirationTimeInMs = Long.MIN_VALUE;

    /**
     * The type of the subscription.  This is defined by the provider and the value is provider
     * specific.
     */
    public String subscriptionType = null;

    /**
     * The time period for usage statistics accumulation. A value of zero means that usage
     * statistics are not accumulated on a periodic basis (e.g., a one-time limit for
     * “pay as you go” - PAYG service). A non-zero value specifies the usage interval in minutes.
     */
    public long usageLimitUsageTimePeriodInMinutes = Long.MIN_VALUE;

    /**
     * The time at which usage statistic accumulation  begins.  It is in the format of number
     * of milliseconds since January 1, 1970, 00:00:00 GMT.
     *
     * Use Long.MIN_VALUE to indicate unset value.
     */
    public long usageLimitStartTimeInMs = Long.MIN_VALUE;

    /**
     * The cumulative data limit in megabytes for the {@link #usageLimitUsageTimePeriodInMinutes}.
     * A value of zero indicate unlimited data usage.
     *
     * Use Long.MIN_VALUE to indicate unset value.
     */
    public long usageLimitDataLimit = Long.MIN_VALUE;

    /**
     * The cumulative time limit in minutes for the {@link #usageLimitUsageTimePeriodInMinutes}.
     * A value of zero indicate unlimited time usage.
     */
    public long usageLimitTimeLimitInMinutes = Long.MIN_VALUE;


    /**
     * Constructor for creating PasspointConfiguration with default values.
     */
@@ -47,7 +152,10 @@ public final class PasspointConfiguration implements Parcelable {
     * @param source The source to copy from
     */
    public PasspointConfiguration(PasspointConfiguration source) {
        if (source != null) {
        if (source == null) {
            return;
        }

        if (source.homeSp != null) {
            homeSp = new HomeSP(source.homeSp);
        }
@@ -57,7 +165,21 @@ public final class PasspointConfiguration implements Parcelable {
        if (source.policy != null) {
            policy = new Policy(source.policy);
        }
        if (source.trustRootCertList != null) {
            trustRootCertList = Collections.unmodifiableMap(source.trustRootCertList);
        }
        if (source.subscriptionUpdate != null) {
            subscriptionUpdate = new UpdateParameter(source.subscriptionUpdate);
        }
        updateIdentifier = source.updateIdentifier;
        credentialPriority = source.credentialPriority;
        subscriptionCreationTimeInMs = source.subscriptionCreationTimeInMs;
        subscriptionExpirationTimeInMs = source.subscriptionExpirationTimeInMs;
        subscriptionType = source.subscriptionType;
        usageLimitDataLimit = source.usageLimitDataLimit;
        usageLimitStartTimeInMs = source.usageLimitStartTimeInMs;
        usageLimitTimeLimitInMinutes = source.usageLimitTimeLimitInMinutes;
        usageLimitUsageTimePeriodInMinutes = source.usageLimitUsageTimePeriodInMinutes;
    }

    @Override
@@ -70,6 +192,17 @@ public final class PasspointConfiguration implements Parcelable {
        dest.writeParcelable(homeSp, flags);
        dest.writeParcelable(credential, flags);
        dest.writeParcelable(policy, flags);
        dest.writeParcelable(subscriptionUpdate, flags);
        writeTrustRootCerts(dest, trustRootCertList);
        dest.writeInt(updateIdentifier);
        dest.writeInt(credentialPriority);
        dest.writeLong(subscriptionCreationTimeInMs);
        dest.writeLong(subscriptionExpirationTimeInMs);
        dest.writeString(subscriptionType);
        dest.writeLong(usageLimitUsageTimePeriodInMinutes);
        dest.writeLong(usageLimitStartTimeInMs);
        dest.writeLong(usageLimitDataLimit);
        dest.writeLong(usageLimitTimeLimitInMinutes);
    }

    @Override
@@ -82,9 +215,21 @@ public final class PasspointConfiguration implements Parcelable {
        }
        PasspointConfiguration that = (PasspointConfiguration) thatObject;
        return (homeSp == null ? that.homeSp == null : homeSp.equals(that.homeSp))
                && (credential == null ? that.credential == null :
                    credential.equals(that.credential))
                && (policy == null) ? that.policy == null : policy.equals(that.policy);
                && (credential == null ? that.credential == null
                        : credential.equals(that.credential))
                && (policy == null) ? that.policy == null : policy.equals(that.policy)
                && (subscriptionUpdate == null) ? that.subscriptionUpdate == null
                        : subscriptionUpdate.equals(that.subscriptionUpdate)
                && isTrustRootCertListEquals(trustRootCertList, that.trustRootCertList)
                && updateIdentifier == that.updateIdentifier
                && credentialPriority == that.credentialPriority
                && subscriptionCreationTimeInMs == that.subscriptionCreationTimeInMs
                && subscriptionExpirationTimeInMs == that.subscriptionExpirationTimeInMs
                && TextUtils.equals(subscriptionType, that.subscriptionType)
                && usageLimitUsageTimePeriodInMinutes == that.usageLimitUsageTimePeriodInMinutes
                && usageLimitStartTimeInMs == that.usageLimitStartTimeInMs
                && usageLimitDataLimit == that.usageLimitDataLimit
                && usageLimitTimeLimitInMinutes == that .usageLimitTimeLimitInMinutes;
    }

    /**
@@ -102,6 +247,34 @@ public final class PasspointConfiguration implements Parcelable {
        if (policy != null && !policy.validate()) {
            return false;
        }
        if (subscriptionUpdate != null && !subscriptionUpdate.validate()) {
            return false;
        }
        if (trustRootCertList != null) {
            for (Map.Entry<String, byte[]> entry : trustRootCertList.entrySet()) {
                String url = entry.getKey();
                byte[] certFingerprint = entry.getValue();
                if (TextUtils.isEmpty(url)) {
                    Log.d(TAG, "Empty URL");
                    return false;
                }
                if (url.getBytes(StandardCharsets.UTF_8).length > MAX_URL_BYTES) {
                    Log.d(TAG, "URL bytes exceeded the max: "
                            + url.getBytes(StandardCharsets.UTF_8).length);
                    return false;
                }

                if (certFingerprint == null) {
                    Log.d(TAG, "Fingerprint not specified");
                    return false;
                }
                if (certFingerprint.length != CERTIFICATE_SHA256_BYTES) {
                    Log.d(TAG, "Incorrect size of trust root certificate SHA-256 fingerprint: "
                            + certFingerprint.length);
                    return false;
                }
            }
        }
        return true;
    }

@@ -113,11 +286,87 @@ public final class PasspointConfiguration implements Parcelable {
                config.homeSp = in.readParcelable(null);
                config.credential = in.readParcelable(null);
                config.policy = in.readParcelable(null);
                config.subscriptionUpdate = in.readParcelable(null);
                config.trustRootCertList = readTrustRootCerts(in);
                config.updateIdentifier = in.readInt();
                config.credentialPriority = in.readInt();
                config.subscriptionCreationTimeInMs = in.readLong();
                config.subscriptionExpirationTimeInMs = in.readLong();
                config.subscriptionType = in.readString();
                config.usageLimitUsageTimePeriodInMinutes = in.readLong();
                config.usageLimitStartTimeInMs = in.readLong();
                config.usageLimitDataLimit = in.readLong();
                config.usageLimitTimeLimitInMinutes = in.readLong();
                return config;
            }

            @Override
            public PasspointConfiguration[] newArray(int size) {
                return new PasspointConfiguration[size];
            }

            /**
             * Helper function for reading trust root certificate info list from a Parcel.
             *
             * @param in The Parcel to read from
             * @return The list of trust root certificate URL with the corresponding certificate
             *         fingerprint
             */
            private Map<String, byte[]> readTrustRootCerts(Parcel in) {
                int size = in.readInt();
                if (size == NULL_VALUE) {
                    return null;
                }
                Map<String, byte[]> trustRootCerts = new HashMap<>(size);
                for (int i = 0; i < size; i++) {
                    String key = in.readString();
                    byte[] value = in.createByteArray();
                    trustRootCerts.put(key, value);
                }
                return trustRootCerts;
            }
        };

    /**
     * Helper function for writing trust root certificate information list.
     *
     * @param dest The Parcel to write to
     * @param trustRootCerts The list of trust root certificate URL with the corresponding
     *                       certificate fingerprint
     */
    private static void writeTrustRootCerts(Parcel dest, Map<String, byte[]> trustRootCerts) {
        if (trustRootCerts == null) {
            dest.writeInt(NULL_VALUE);
            return;
        }
        dest.writeInt(trustRootCerts.size());
        for (Map.Entry<String, byte[]> entry : trustRootCerts.entrySet()) {
            dest.writeString(entry.getKey());
            dest.writeByteArray(entry.getValue());
        }
    }

    /**
     * Helper function for comparing two trust root certificate list.  Cannot use Map#equals
     * method since the value type (byte[]) doesn't override equals method.
     *
     * @param list1 The first trust root certificate list
     * @param list2 The second trust root certificate list
     * @return true if the two list are equal
     */
    private static boolean isTrustRootCertListEquals(Map<String, byte[]> list1,
            Map<String, byte[]> list2) {
        if (list1 == null || list2 == null) {
            return list1 == list2;
        }
        if (list1.size() != list2.size()) {
            return false;
        }
        for (Map.Entry<String, byte[]> entry : list1.entrySet()) {
            if (!Arrays.equals(entry.getValue(), list2.get(entry.getKey()))) {
                return false;
            }
        }
        return true;
    }
}
+168 −40

File changed.

Preview size limit exceeded, changes collapsed.

+97 −0
Original line number Diff line number Diff line
@@ -7,6 +7,10 @@
        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
      </Type>
    </RTProperties>
    <Node>
      <NodeName>UpdateIdentifier</NodeName>
      <Value>12</Value>
    </Node>
    <Node>
      <NodeName>i001</NodeName>
      <Node>
@@ -297,6 +301,99 @@
          <Value>23</Value>
        </Node>
      </Node>
      <Node>
        <NodeName>CredentialPriority</NodeName>
        <Value>99</Value>
      </Node>
      <Node>
        <NodeName>AAAServerTrustRoot</NodeName>
        <Node>
          <NodeName>a001</NodeName>
          <Node>
            <NodeName>CertURL</NodeName>
            <Value>server1.trust.root.com</Value>
          </Node>
          <Node>
            <NodeName>CertSHA256Fingerprint</NodeName>
            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
          </Node>
        </Node>
      </Node>
      <Node>
        <NodeName>SubscriptionUpdate</NodeName>
        <Node>
          <NodeName>UpdateInterval</NodeName>
          <Value>120</Value>
        </Node>
        <Node>
          <NodeName>UpdateMethod</NodeName>
          <Value>SSP-ClientInitiated</Value>
        </Node>
        <Node>
          <NodeName>Restriction</NodeName>
          <Value>RoamingPartner</Value>
        </Node>
        <Node>
          <NodeName>URI</NodeName>
          <Value>subscription.update.com</Value>
        </Node>
        <Node>
          <NodeName>UsernamePassword</NodeName>
          <Node>
            <NodeName>Username</NodeName>
            <Value>subscriptionUser</Value>
          </Node>
          <Node>
            <NodeName>Password</NodeName>
            <Value>subscriptionPass</Value>
          </Node>
        </Node>
        <Node>
          <NodeName>TrustRoot</NodeName>
          <Node>
            <NodeName>CertURL</NodeName>
            <Value>subscription.update.cert.com</Value>
          </Node>
          <Node>
            <NodeName>CertSHA256Fingerprint</NodeName>
            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
          </Node>
        </Node>
      </Node>
      <Node>
        <NodeName>SubscriptionParameter</NodeName>
        <Node>
          <NodeName>CreationDate</NodeName>
          <Value>2016-02-01T10:00:00Z</Value>
        </Node>
        <Node>
          <NodeName>ExpirationDate</NodeName>
          <Value>2016-03-01T10:00:00Z</Value>
        </Node>
        <Node>
          <NodeName>TypeOfSubscription</NodeName>
          <Value>Gold</Value>
        </Node>
        <Node>
          <NodeName>UsageLimits</NodeName>
          <Node>
            <NodeName>DataLimit</NodeName>
            <Value>921890</Value>
          </Node>
          <Node>
            <NodeName>StartDate</NodeName>
            <Value>2016-12-01T10:00:00Z</Value>
          </Node>
          <Node>
            <NodeName>TimeLimit</NodeName>
            <Value>120</Value>
          </Node>
          <Node>
            <NodeName>UsageTimePeriod</NodeName>
            <Value>99910</Value>
          </Node>
        </Node>
      </Node>
    </Node>
  </Node>
</MgmtTree>
+113 −1
Original line number Diff line number Diff line
@@ -30,7 +30,9 @@ import android.util.Base64;

import org.junit.Test;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

/**
@@ -38,6 +40,8 @@ import java.util.HashMap;
 */
@SmallTest
public class PasspointConfigurationTest {
    private static final int MAX_URL_BYTES = 1023;
    private static final int CERTIFICATE_FINGERPRINT_BYTES = 32;

    /**
     * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}.
@@ -111,11 +115,25 @@ public class PasspointConfigurationTest {
        policy.policyUpdate.base64EncodedPassword =
                Base64.encodeToString("password".getBytes(), Base64.DEFAULT);
        policy.policyUpdate.trustRootCertUrl = "trust.cert.com";
        policy.policyUpdate.trustRootCertSha256Fingerprint = new byte[32];
        policy.policyUpdate.trustRootCertSha256Fingerprint =
                new byte[CERTIFICATE_FINGERPRINT_BYTES];

        return policy;
    }

    private static UpdateParameter createSubscriptionUpdate() {
        UpdateParameter subUpdate = new UpdateParameter();
        subUpdate.updateIntervalInMinutes = 9021;
        subUpdate.updateMethod = UpdateParameter.UPDATE_METHOD_SSP;
        subUpdate.restriction = UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER;
        subUpdate.serverUri = "subscription.update.com";
        subUpdate.username = "subUsername";
        subUpdate.base64EncodedPassword =
                Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT);
        subUpdate.trustRootCertUrl = "subscription.trust.cert.com";
        subUpdate.trustRootCertSha256Fingerprint = new byte[CERTIFICATE_FINGERPRINT_BYTES];
        return subUpdate;
    }
    /**
     * Helper function for creating a {@link PasspointConfiguration} for testing.
     *
@@ -126,6 +144,21 @@ public class PasspointConfigurationTest {
        config.homeSp = createHomeSp();
        config.credential = createCredential();
        config.policy = createPolicy();
        config.subscriptionUpdate = createSubscriptionUpdate();
        config.trustRootCertList = new HashMap<>();
        config.trustRootCertList.put("trustRoot.cert1.com",
                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
        config.trustRootCertList.put("trustRoot.cert2.com",
                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
        config.updateIdentifier = 1;
        config.credentialPriority = 120;
        config.subscriptionCreationTimeInMs = 231200;
        config.subscriptionExpirationTimeInMs = 2134232;
        config.subscriptionType = "Gold";
        config.usageLimitUsageTimePeriodInMinutes = 3600;
        config.usageLimitStartTimeInMs = 124214213;
        config.usageLimitDataLimit = 14121;
        config.usageLimitTimeLimitInMinutes = 78912;
        return config;
    }

@@ -201,6 +234,31 @@ public class PasspointConfigurationTest {
        verifyParcel(config);
    }

    /**
     * Verify parcel read/write for a configuration that doesn't contain subscription update.
     *
     * @throws Exception
     */
    @Test
    public void verifyParcelWithoutSubscriptionUpdate() throws Exception {
        PasspointConfiguration config = createConfig();
        config.subscriptionUpdate = null;
        verifyParcel(config);
    }

    /**
     * Verify parcel read/write for a configuration that doesn't contain trust root certificate
     * list.
     *
     * @throws Exception
     */
    @Test
    public void verifyParcelWithoutTrustRootCertList() throws Exception {
        PasspointConfiguration config = createConfig();
        config.trustRootCertList = null;
        verifyParcel(config);
    }

    /**
     * Verify that a default/empty configuration is invalid.
     *
@@ -260,6 +318,60 @@ public class PasspointConfigurationTest {
        assertTrue(config.validate());
    }

    /**
     * Verify that a configuration without subscription update is valid, since subscription
     * update configurations are optional (applied for Hotspot 2.0 Release only).
     *
     * @throws Exception
     */
    @Test
    public void validateConfigWithoutSubscriptionUpdate() throws Exception {
        PasspointConfiguration config = createConfig();
        config.subscriptionUpdate = null;
        assertTrue(config.validate());
    }

    /**
     * Verify that a configuration with a trust root certificate URL exceeding the max size
     * is invalid.
     *
     * @throws Exception
     */
    @Test
    public void validateConfigWithInvalidTrustRootCertUrl() throws Exception {
        PasspointConfiguration config = createConfig();
        byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1];
        Arrays.fill(rawUrlBytes, (byte) 'a');
        config.trustRootCertList.put(new String(rawUrlBytes, StandardCharsets.UTF_8),
                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
        assertFalse(config.validate());

        config.trustRootCertList = new HashMap<>();
        config.trustRootCertList.put(null, new byte[CERTIFICATE_FINGERPRINT_BYTES]);
        assertFalse(config.validate());
    }

    /**
     * Verify that a configuration with an invalid trust root certificate fingerprint is invalid.
     *
     * @throws Exception
     */
    @Test
    public void validateConfigWithInvalidTrustRootCertFingerprint() throws Exception {
        PasspointConfiguration config = createConfig();
        config.trustRootCertList = new HashMap<>();
        config.trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES + 1]);
        assertFalse(config.validate());

        config.trustRootCertList = new HashMap<>();
        config.trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES - 1]);
        assertFalse(config.validate());

        config.trustRootCertList = new HashMap<>();
        config.trustRootCertList.put("test.cert.com", null);
        assertFalse(config.validate());
    }

    /**
     * Verify that copy constructor works when pass in a null source.
     *
+32 −3
Original line number Diff line number Diff line
@@ -85,7 +85,38 @@ public class PPSMOParserTest {
     * @return {@link PasspointConfiguration}
     */
    private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

        PasspointConfiguration config = new PasspointConfiguration();
        config.updateIdentifier = 12;
        config.credentialPriority = 99;

        // AAA Server trust root.
        config.trustRootCertList = new HashMap<>();
        byte[] certFingerprint = new byte[32];
        Arrays.fill(certFingerprint, (byte) 0x1f);
        config.trustRootCertList.put("server1.trust.root.com", certFingerprint);

        // Subscription update.
        config.subscriptionUpdate = new UpdateParameter();
        config.subscriptionUpdate.updateIntervalInMinutes = 120;
        config.subscriptionUpdate.updateMethod = UpdateParameter.UPDATE_METHOD_SSP;
        config.subscriptionUpdate.restriction = UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER;
        config.subscriptionUpdate.serverUri = "subscription.update.com";
        config.subscriptionUpdate.username = "subscriptionUser";
        config.subscriptionUpdate.base64EncodedPassword = "subscriptionPass";
        config.subscriptionUpdate.trustRootCertUrl = "subscription.update.cert.com";
        config.subscriptionUpdate.trustRootCertSha256Fingerprint = new byte[32];
        Arrays.fill(config.subscriptionUpdate.trustRootCertSha256Fingerprint, (byte) 0x1f);

        // Subscription parameters.
        config.subscriptionCreationTimeInMs = format.parse("2016-02-01T10:00:00Z").getTime();
        config.subscriptionExpirationTimeInMs = format.parse("2016-03-01T10:00:00Z").getTime();
        config.subscriptionType = "Gold";
        config.usageLimitDataLimit = 921890;
        config.usageLimitStartTimeInMs = format.parse("2016-12-01T10:00:00Z").getTime();
        config.usageLimitTimeLimitInMinutes = 120;
        config.usageLimitUsageTimePeriodInMinutes = 99910;

        // HomeSP configuration.
        config.homeSp = new HomeSP();
@@ -101,7 +132,6 @@ public class PPSMOParserTest {
        config.homeSp.otherHomePartners = new String[] {"other.fqdn.com"};

        // Credential configuration.
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        config.credential = new Credential();
        config.credential.creationTimeInMs = format.parse("2016-01-01T10:00:00Z").getTime();
        config.credential.expirationTimeInMs = format.parse("2016-02-01T10:00:00Z").getTime();
@@ -161,8 +191,7 @@ public class PPSMOParserTest {
    }

    /**
     * Parse and verify all supported fields under PPS MO tree (currently only fields under
     * HomeSP and Credential subtree).
     * Parse and verify all supported fields under PPS MO tree.
     *
     * @throws Exception
     */