1 /*
2  * Copyright (C) 2014 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 
17 package android.net;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.SuppressLint;
22 import android.annotation.SystemApi;
23 import android.compat.annotation.UnsupportedAppUsage;
24 import android.os.Build;
25 import android.os.Parcel;
26 import android.os.Parcelable;
27 
28 import java.util.Objects;
29 
30 /**
31  * A class representing the IP configuration of a network.
32  */
33 public final class IpConfiguration implements Parcelable {
34     private static final String TAG = "IpConfiguration";
35 
36     // This enum has been used by apps through reflection for many releases.
37     // Therefore they can't just be removed. Duplicating these constants to
38     // give an alternate SystemApi is a worse option than exposing them.
39     /** @hide */
40     @SystemApi
41     @SuppressLint("Enum")
42     public enum IpAssignment {
43         /* Use statically configured IP settings. Configuration can be accessed
44          * with staticIpConfiguration */
45         STATIC,
46         /* Use dynamically configured IP settings */
47         DHCP,
48         /* no IP details are assigned, this is used to indicate
49          * that any existing IP settings should be retained */
50         UNASSIGNED
51     }
52 
53     /** @hide */
54     public IpAssignment ipAssignment;
55 
56     /** @hide */
57     public StaticIpConfiguration staticIpConfiguration;
58 
59     // This enum has been used by apps through reflection for many releases.
60     // Therefore they can't just be removed. Duplicating these constants to
61     // give an alternate SystemApi is a worse option than exposing them.
62     /** @hide */
63     @SystemApi
64     @SuppressLint("Enum")
65     public enum ProxySettings {
66         /* No proxy is to be used. Any existing proxy settings
67          * should be cleared. */
68         NONE,
69         /* Use statically configured proxy. Configuration can be accessed
70          * with httpProxy. */
71         STATIC,
72         /* no proxy details are assigned, this is used to indicate
73          * that any existing proxy settings should be retained */
74         UNASSIGNED,
75         /* Use a Pac based proxy.
76          */
77         PAC
78     }
79 
80     /** @hide */
81     public ProxySettings proxySettings;
82 
83     /** @hide */
84     @UnsupportedAppUsage
85     public ProxyInfo httpProxy;
86 
init(IpAssignment ipAssignment, ProxySettings proxySettings, StaticIpConfiguration staticIpConfiguration, ProxyInfo httpProxy)87     private void init(IpAssignment ipAssignment,
88                       ProxySettings proxySettings,
89                       StaticIpConfiguration staticIpConfiguration,
90                       ProxyInfo httpProxy) {
91         this.ipAssignment = ipAssignment;
92         this.proxySettings = proxySettings;
93         this.staticIpConfiguration = (staticIpConfiguration == null) ?
94                 null : new StaticIpConfiguration(staticIpConfiguration);
95         this.httpProxy = (httpProxy == null) ?
96                 null : new ProxyInfo(httpProxy);
97     }
98 
99     /** @hide */
100     @SystemApi
IpConfiguration()101     public IpConfiguration() {
102         init(IpAssignment.UNASSIGNED, ProxySettings.UNASSIGNED, null, null);
103     }
104 
105     /** @hide */
106     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
IpConfiguration(IpAssignment ipAssignment, ProxySettings proxySettings, StaticIpConfiguration staticIpConfiguration, ProxyInfo httpProxy)107     public IpConfiguration(IpAssignment ipAssignment,
108                            ProxySettings proxySettings,
109                            StaticIpConfiguration staticIpConfiguration,
110                            ProxyInfo httpProxy) {
111         init(ipAssignment, proxySettings, staticIpConfiguration, httpProxy);
112     }
113 
114     /** @hide */
115     @SystemApi
IpConfiguration(@onNull IpConfiguration source)116     public IpConfiguration(@NonNull IpConfiguration source) {
117         this();
118         if (source != null) {
119             init(source.ipAssignment, source.proxySettings,
120                  source.staticIpConfiguration, source.httpProxy);
121         }
122     }
123 
124     /** @hide */
125     @SystemApi
getIpAssignment()126     public @NonNull IpAssignment getIpAssignment() {
127         return ipAssignment;
128     }
129 
130     /** @hide */
131     @SystemApi
setIpAssignment(@onNull IpAssignment ipAssignment)132     public void setIpAssignment(@NonNull IpAssignment ipAssignment) {
133         this.ipAssignment = ipAssignment;
134     }
135 
136     /**
137      * Get the current static IP configuration (possibly null). Configured via
138      * {@link Builder#setStaticIpConfiguration(StaticIpConfiguration)}.
139      *
140      * @return Current static IP configuration.
141      */
getStaticIpConfiguration()142     public @Nullable StaticIpConfiguration getStaticIpConfiguration() {
143         return staticIpConfiguration;
144     }
145 
146     /** @hide */
147     @SystemApi
setStaticIpConfiguration(@ullable StaticIpConfiguration staticIpConfiguration)148     public void setStaticIpConfiguration(@Nullable StaticIpConfiguration staticIpConfiguration) {
149         this.staticIpConfiguration = staticIpConfiguration;
150     }
151 
152     /** @hide */
153     @SystemApi
getProxySettings()154     public @NonNull ProxySettings getProxySettings() {
155         return proxySettings;
156     }
157 
158     /** @hide */
159     @SystemApi
setProxySettings(@onNull ProxySettings proxySettings)160     public void setProxySettings(@NonNull ProxySettings proxySettings) {
161         this.proxySettings = proxySettings;
162     }
163 
164     /**
165      * The proxy configuration of this object.
166      *
167      * @return The proxy information of this object configured via
168      * {@link Builder#setHttpProxy(ProxyInfo)}.
169      */
getHttpProxy()170     public @Nullable ProxyInfo getHttpProxy() {
171         return httpProxy;
172     }
173 
174     /** @hide */
175     @SystemApi
setHttpProxy(@ullable ProxyInfo httpProxy)176     public void setHttpProxy(@Nullable ProxyInfo httpProxy) {
177         this.httpProxy = httpProxy;
178     }
179 
180     @Override
toString()181     public String toString() {
182         StringBuilder sbuf = new StringBuilder();
183         sbuf.append("IP assignment: " + ipAssignment.toString());
184         sbuf.append("\n");
185         if (staticIpConfiguration != null) {
186             sbuf.append("Static configuration: " + staticIpConfiguration.toString());
187             sbuf.append("\n");
188         }
189         sbuf.append("Proxy settings: " + proxySettings.toString());
190         sbuf.append("\n");
191         if (httpProxy != null) {
192             sbuf.append("HTTP proxy: " + httpProxy.toString());
193             sbuf.append("\n");
194         }
195 
196         return sbuf.toString();
197     }
198 
199     @Override
equals(@ullable Object o)200     public boolean equals(@Nullable Object o) {
201         if (o == this) {
202             return true;
203         }
204 
205         if (!(o instanceof IpConfiguration)) {
206             return false;
207         }
208 
209         IpConfiguration other = (IpConfiguration) o;
210         return this.ipAssignment == other.ipAssignment &&
211                 this.proxySettings == other.proxySettings &&
212                 Objects.equals(this.staticIpConfiguration, other.staticIpConfiguration) &&
213                 Objects.equals(this.httpProxy, other.httpProxy);
214     }
215 
216     @Override
hashCode()217     public int hashCode() {
218         return 13 + (staticIpConfiguration != null ? staticIpConfiguration.hashCode() : 0) +
219                17 * ipAssignment.ordinal() +
220                47 * proxySettings.ordinal() +
221                83 * httpProxy.hashCode();
222     }
223 
224     /** Implement the Parcelable interface */
describeContents()225     public int describeContents() {
226         return 0;
227     }
228 
229     /** Implement the Parcelable interface */
writeToParcel(@onNull Parcel dest, int flags)230     public void writeToParcel(@NonNull Parcel dest, int flags) {
231         dest.writeString(ipAssignment.name());
232         dest.writeString(proxySettings.name());
233         dest.writeParcelable(staticIpConfiguration, flags);
234         dest.writeParcelable(httpProxy, flags);
235     }
236 
237     /** Implement the Parcelable interface */
238     public static final @NonNull Creator<IpConfiguration> CREATOR =
239         new Creator<IpConfiguration>() {
240             public IpConfiguration createFromParcel(Parcel in) {
241                 IpConfiguration config = new IpConfiguration();
242                 config.ipAssignment = IpAssignment.valueOf(in.readString());
243                 config.proxySettings = ProxySettings.valueOf(in.readString());
244                 config.staticIpConfiguration = in.readParcelable(null);
245                 config.httpProxy = in.readParcelable(null);
246                 return config;
247             }
248 
249             public IpConfiguration[] newArray(int size) {
250                 return new IpConfiguration[size];
251             }
252         };
253 
254     /**
255      * Builder used to construct {@link IpConfiguration} objects.
256      */
257     public static final class Builder {
258         private StaticIpConfiguration mStaticIpConfiguration;
259         private ProxyInfo mProxyInfo;
260 
261         /**
262          * Set a static IP configuration.
263          *
264          * @param config Static IP configuration.
265          * @return A {@link Builder} object to allow chaining.
266          */
setStaticIpConfiguration(@ullable StaticIpConfiguration config)267         public @NonNull Builder setStaticIpConfiguration(@Nullable StaticIpConfiguration config) {
268             mStaticIpConfiguration = config;
269             return this;
270         }
271 
272         /**
273          * Set a proxy configuration.
274          *
275          * @param proxyInfo Proxy configuration.
276          * @return A {@link Builder} object to allow chaining.
277          */
setHttpProxy(@ullable ProxyInfo proxyInfo)278         public @NonNull Builder setHttpProxy(@Nullable ProxyInfo proxyInfo) {
279             mProxyInfo = proxyInfo;
280             return this;
281         }
282 
283         /**
284          * Construct an {@link IpConfiguration}.
285          *
286          * @return A new {@link IpConfiguration} object.
287          */
build()288         public @NonNull IpConfiguration build() {
289             IpConfiguration config = new IpConfiguration();
290             config.setStaticIpConfiguration(mStaticIpConfiguration);
291             config.setIpAssignment(
292                     mStaticIpConfiguration == null ? IpAssignment.DHCP : IpAssignment.STATIC);
293 
294             config.setHttpProxy(mProxyInfo);
295             if (mProxyInfo == null) {
296                 config.setProxySettings(ProxySettings.NONE);
297             } else {
298                 config.setProxySettings(
299                         mProxyInfo.getPacFileUrl() == null ? ProxySettings.STATIC
300                                 : ProxySettings.PAC);
301             }
302             return config;
303         }
304     }
305 }
306