1971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey/*
2971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * Copyright (C) 2011 The Android Open Source Project
3971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey *
4971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * you may not use this file except in compliance with the License.
6971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * You may obtain a copy of the License at
7971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey *
8971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey *
10971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
11971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * See the License for the specific language governing permissions and
14971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * limitations under the License.
15971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey */
16971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
17971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkeypackage com.android.internal.net;
18971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
1982f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkeyimport android.os.Parcel;
2082f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkeyimport android.os.Parcelable;
2169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkeyimport android.text.TextUtils;
2269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkeyimport android.util.Log;
2382f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey
2469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkeyimport java.net.InetAddress;
25971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkeyimport java.nio.charset.Charsets;
26971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
27971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey/**
28971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * Parcel-like entity class for VPN profiles. To keep things simple, all
29971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * fields are package private. Methods are provided for serialization, so
30971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * storage can be implemented easily. Two rules are set for this class.
31971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * First, all fields must be kept non-null. Second, always make a copy
32971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * using clone() before modifying.
33971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey *
34971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * @hide
35971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey */
3682f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkeypublic class VpnProfile implements Cloneable, Parcelable {
3769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    private static final String TAG = "VpnProfile";
3869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
39971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    // Match these constants with R.array.vpn_types.
40971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_PPTP = 0;
41971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_L2TP_IPSEC_PSK = 1;
42971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_L2TP_IPSEC_RSA = 2;
43971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_IPSEC_XAUTH_PSK = 3;
44971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_IPSEC_XAUTH_RSA = 4;
45971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_IPSEC_HYBRID_RSA = 5;
46971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_MAX = 5;
47971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
48971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    // Entity fields.
49971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public final String key;           // -1
50971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String name = "";           // 0
51971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public int type = TYPE_PPTP;       // 1
52971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String server = "";         // 2
53971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String username = "";       // 3
54971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String password = "";       // 4
55971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String dnsServers = "";     // 5
56971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String searchDomains = "";  // 6
57971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String routes = "";         // 7
58971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public boolean mppe = true;        // 8
59971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String l2tpSecret = "";     // 9
60971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String ipsecIdentifier = "";// 10
61971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String ipsecSecret = "";    // 11
62971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String ipsecUserCert = "";  // 12
63971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String ipsecCaCert = "";    // 13
64971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String ipsecServerCert = "";// 14
65971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
66971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    // Helper fields.
67971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public boolean saveLogin = false;
68971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
69971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public VpnProfile(String key) {
70971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        this.key = key;
71971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    }
72971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
736e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey    public VpnProfile(Parcel in) {
746e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        key = in.readString();
756e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        name = in.readString();
766e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        type = in.readInt();
776e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        server = in.readString();
786e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        username = in.readString();
796e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        password = in.readString();
806e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        dnsServers = in.readString();
816e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        searchDomains = in.readString();
826e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        routes = in.readString();
836e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        mppe = in.readInt() != 0;
846e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        l2tpSecret = in.readString();
856e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        ipsecIdentifier = in.readString();
866e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        ipsecSecret = in.readString();
876e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        ipsecUserCert = in.readString();
886e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        ipsecCaCert = in.readString();
896e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        ipsecServerCert = in.readString();
906e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        saveLogin = in.readInt() != 0;
916e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey    }
926e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey
936e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey    @Override
946e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey    public void writeToParcel(Parcel out, int flags) {
956e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(key);
966e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(name);
976e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeInt(type);
986e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(server);
996e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(username);
1006e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(password);
1016e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(dnsServers);
1026e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(searchDomains);
1036e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(routes);
1046e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeInt(mppe ? 1 : 0);
1056e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(l2tpSecret);
1066e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(ipsecIdentifier);
1076e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(ipsecSecret);
1086e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(ipsecUserCert);
1096e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(ipsecCaCert);
1106e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(ipsecServerCert);
1116e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeInt(saveLogin ? 1 : 0);
1126e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey    }
1136e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey
114971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static VpnProfile decode(String key, byte[] value) {
115971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        try {
116971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            if (key == null) {
117971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey                return null;
118971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            }
119971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
120971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            String[] values = new String(value, Charsets.UTF_8).split("\0", -1);
121971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            // There can be 14 or 15 values in ICS MR1.
122971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            if (values.length < 14 || values.length > 15) {
123971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey                return null;
124971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            }
125971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
126971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            VpnProfile profile = new VpnProfile(key);
127971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.name = values[0];
128971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.type = Integer.valueOf(values[1]);
129971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            if (profile.type < 0 || profile.type > TYPE_MAX) {
130971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey                return null;
131971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            }
132971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.server = values[2];
133971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.username = values[3];
134971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.password = values[4];
135971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.dnsServers = values[5];
136971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.searchDomains = values[6];
137971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.routes = values[7];
138971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.mppe = Boolean.valueOf(values[8]);
139971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.l2tpSecret = values[9];
140971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.ipsecIdentifier = values[10];
141971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.ipsecSecret = values[11];
142971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.ipsecUserCert = values[12];
143971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.ipsecCaCert = values[13];
144971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.ipsecServerCert = (values.length > 14) ? values[14] : "";
145971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
146971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.saveLogin = !profile.username.isEmpty() || !profile.password.isEmpty();
147971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            return profile;
148971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        } catch (Exception e) {
149971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            // ignore
150971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        }
151971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        return null;
152971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    }
153971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
154971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public byte[] encode() {
155971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        StringBuilder builder = new StringBuilder(name);
156971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(type);
157971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(server);
158971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(saveLogin ? username : "");
159971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(saveLogin ? password : "");
160971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(dnsServers);
161971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(searchDomains);
162971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(routes);
163971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(mppe);
164971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(l2tpSecret);
165971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(ipsecIdentifier);
166971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(ipsecSecret);
167971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(ipsecUserCert);
168971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(ipsecCaCert);
169971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(ipsecServerCert);
170971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        return builder.toString().getBytes(Charsets.UTF_8);
171971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    }
17282f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey
17369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    /**
17469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey     * Test if profile is valid for lockdown, which requires IPv4 address for
17569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey     * both server and DNS. Server hostnames would require using DNS before
17669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey     * connection.
17769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey     */
17869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    public boolean isValidLockdownProfile() {
17969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        try {
18069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            InetAddress.parseNumericAddress(server);
18169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
18269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            for (String dnsServer : dnsServers.split(" +")) {
18369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                InetAddress.parseNumericAddress(this.dnsServers);
18469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            }
18569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            if (TextUtils.isEmpty(dnsServers)) {
18669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                Log.w(TAG, "DNS required");
18769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                return false;
18869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            }
18969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
19069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            // Everything checked out above
19169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            return true;
19269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
19369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        } catch (IllegalArgumentException e) {
19469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            Log.w(TAG, "Invalid address", e);
19569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            return false;
19669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        }
19769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    }
19869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
19982f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey    public static final Creator<VpnProfile> CREATOR = new Creator<VpnProfile>() {
20082f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        @Override
20182f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        public VpnProfile createFromParcel(Parcel in) {
2026e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey            return new VpnProfile(in);
20382f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        }
20482f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey
20582f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        @Override
20682f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        public VpnProfile[] newArray(int size) {
20782f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey            return new VpnProfile[size];
20882f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        }
20982f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey    };
21082f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey
21182f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey    @Override
21282f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey    public int describeContents() {
21382f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        return 0;
21482f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey    }
215971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey}
216