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.SystemApi;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import java.util.Objects;
26 
27 /**
28  * Allows a network transport to provide the system with policy and configuration information about
29  * a particular network when registering a {@link NetworkAgent}. This information cannot change once the agent is registered.
30  *
31  * @hide
32  */
33 @SystemApi
34 public final class NetworkAgentConfig implements Parcelable {
35 
36     /**
37      * If the {@link Network} is a VPN, whether apps are allowed to bypass the
38      * VPN. This is set by a {@link VpnService} and used by
39      * {@link ConnectivityManager} when creating a VPN.
40      *
41      * @hide
42      */
43     public boolean allowBypass;
44 
45     /**
46      * Set if the network was manually/explicitly connected to by the user either from settings
47      * or a 3rd party app.  For example, turning on cell data is not explicit but tapping on a wifi
48      * ap in the wifi settings to trigger a connection is explicit.  A 3rd party app asking to
49      * connect to a particular access point is also explicit, though this may change in the future
50      * as we want apps to use the multinetwork apis.
51      *
52      * @hide
53      */
54     public boolean explicitlySelected;
55 
56     /**
57      * @return whether this network was explicitly selected by the user.
58      */
isExplicitlySelected()59     public boolean isExplicitlySelected() {
60         return explicitlySelected;
61     }
62 
63     /**
64      * Set if the user desires to use this network even if it is unvalidated. This field has meaning
65      * only if {@link explicitlySelected} is true. If it is, this field must also be set to the
66      * appropriate value based on previous user choice.
67      *
68      * TODO : rename this field to match its accessor
69      * @hide
70      */
71     public boolean acceptUnvalidated;
72 
73     /**
74      * @return whether the system should accept this network even if it doesn't validate.
75      */
isUnvalidatedConnectivityAcceptable()76     public boolean isUnvalidatedConnectivityAcceptable() {
77         return acceptUnvalidated;
78     }
79 
80     /**
81      * Whether the user explicitly set that this network should be validated even if presence of
82      * only partial internet connectivity.
83      *
84      * TODO : rename this field to match its accessor
85      * @hide
86      */
87     public boolean acceptPartialConnectivity;
88 
89     /**
90      * @return whether the system should validate this network even if it only offers partial
91      *     Internet connectivity.
92      */
isPartialConnectivityAcceptable()93     public boolean isPartialConnectivityAcceptable() {
94         return acceptPartialConnectivity;
95     }
96 
97     /**
98      * Set to avoid surfacing the "Sign in to network" notification.
99      * if carrier receivers/apps are registered to handle the carrier-specific provisioning
100      * procedure, a carrier specific provisioning notification will be placed.
101      * only one notification should be displayed. This field is set based on
102      * which notification should be used for provisioning.
103      *
104      * @hide
105      */
106     public boolean provisioningNotificationDisabled;
107 
108     /**
109      *
110      * @return whether the sign in to network notification is enabled by this configuration.
111      * @hide
112      */
isProvisioningNotificationEnabled()113     public boolean isProvisioningNotificationEnabled() {
114         return !provisioningNotificationDisabled;
115     }
116 
117     /**
118      * For mobile networks, this is the subscriber ID (such as IMSI).
119      *
120      * @hide
121      */
122     public String subscriberId;
123 
124     /**
125      * @return the subscriber ID, or null if none.
126      * @hide
127      */
128     @Nullable
getSubscriberId()129     public String getSubscriberId() {
130         return subscriberId;
131     }
132 
133     /**
134      * Set to skip 464xlat. This means the device will treat the network as IPv6-only and
135      * will not attempt to detect a NAT64 via RFC 7050 DNS lookups.
136      *
137      * @hide
138      */
139     public boolean skip464xlat;
140 
141     /**
142      * @return whether NAT64 prefix detection is enabled.
143      * @hide
144      */
isNat64DetectionEnabled()145     public boolean isNat64DetectionEnabled() {
146         return !skip464xlat;
147     }
148 
149     /**
150      * The legacy type of this network agent, or TYPE_NONE if unset.
151      * @hide
152      */
153     public int legacyType = ConnectivityManager.TYPE_NONE;
154 
155     /**
156      * @return the legacy type
157      */
158     @ConnectivityManager.LegacyNetworkType
getLegacyType()159     public int getLegacyType() {
160         return legacyType;
161     }
162 
163     /**
164      * Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network.
165      * Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode.
166      *
167      * This is not parceled, because it would not make sense.
168      *
169      * @hide
170      */
171     public transient boolean hasShownBroken;
172 
173     /**
174      * The name of the legacy network type. It's a free-form string used in logging.
175      * @hide
176      */
177     @NonNull
178     public String legacyTypeName = "";
179 
180     /**
181      * @return the name of the legacy network type. It's a free-form string used in logging.
182      */
183     @NonNull
getLegacyTypeName()184     public String getLegacyTypeName() {
185         return legacyTypeName;
186     }
187 
188     /**
189      * The legacy extra info of the agent. The extra info should only be :
190      * <ul>
191      *   <li>For cellular agents, the APN name.</li>
192      *   <li>For ethernet agents, the interface name.</li>
193      * </ul>
194      * @hide
195      */
196     @NonNull
197     private String mLegacyExtraInfo = "";
198 
199     /**
200      * The legacy extra info of the agent.
201      * @hide
202      */
203     @NonNull
getLegacyExtraInfo()204     public String getLegacyExtraInfo() {
205         return mLegacyExtraInfo;
206     }
207 
208     /** @hide */
NetworkAgentConfig()209     public NetworkAgentConfig() {
210     }
211 
212     /** @hide */
NetworkAgentConfig(@ullable NetworkAgentConfig nac)213     public NetworkAgentConfig(@Nullable NetworkAgentConfig nac) {
214         if (nac != null) {
215             allowBypass = nac.allowBypass;
216             explicitlySelected = nac.explicitlySelected;
217             acceptUnvalidated = nac.acceptUnvalidated;
218             acceptPartialConnectivity = nac.acceptPartialConnectivity;
219             subscriberId = nac.subscriberId;
220             provisioningNotificationDisabled = nac.provisioningNotificationDisabled;
221             skip464xlat = nac.skip464xlat;
222             legacyType = nac.legacyType;
223             legacyTypeName = nac.legacyTypeName;
224             mLegacyExtraInfo = nac.mLegacyExtraInfo;
225         }
226     }
227 
228     /**
229      * Builder class to facilitate constructing {@link NetworkAgentConfig} objects.
230      */
231     public static final class Builder {
232         private final NetworkAgentConfig mConfig = new NetworkAgentConfig();
233 
234         /**
235          * Sets whether the network was explicitly selected by the user.
236          *
237          * @return this builder, to facilitate chaining.
238          */
239         @NonNull
setExplicitlySelected(final boolean explicitlySelected)240         public Builder setExplicitlySelected(final boolean explicitlySelected) {
241             mConfig.explicitlySelected = explicitlySelected;
242             return this;
243         }
244 
245         /**
246          * Sets whether the system should validate this network even if it is found not to offer
247          * Internet connectivity.
248          *
249          * @return this builder, to facilitate chaining.
250          */
251         @NonNull
setUnvalidatedConnectivityAcceptable( final boolean unvalidatedConnectivityAcceptable)252         public Builder setUnvalidatedConnectivityAcceptable(
253                 final boolean unvalidatedConnectivityAcceptable) {
254             mConfig.acceptUnvalidated = unvalidatedConnectivityAcceptable;
255             return this;
256         }
257 
258         /**
259          * Sets whether the system should validate this network even if it is found to only offer
260          * partial Internet connectivity.
261          *
262          * @return this builder, to facilitate chaining.
263          */
264         @NonNull
setPartialConnectivityAcceptable( final boolean partialConnectivityAcceptable)265         public Builder setPartialConnectivityAcceptable(
266                 final boolean partialConnectivityAcceptable) {
267             mConfig.acceptPartialConnectivity = partialConnectivityAcceptable;
268             return this;
269         }
270 
271         /**
272          * Sets the subscriber ID for this network.
273          *
274          * @return this builder, to facilitate chaining.
275          * @hide
276          */
277         @NonNull
setSubscriberId(@ullable String subscriberId)278         public Builder setSubscriberId(@Nullable String subscriberId) {
279             mConfig.subscriberId = subscriberId;
280             return this;
281         }
282 
283         /**
284          * Disables active detection of NAT64 (e.g., via RFC 7050 DNS lookups). Used to save power
285          * and reduce idle traffic on networks that are known to be IPv6-only without a NAT64.
286          *
287          * @return this builder, to facilitate chaining.
288          * @hide
289          */
290         @NonNull
disableNat64Detection()291         public Builder disableNat64Detection() {
292             mConfig.skip464xlat = true;
293             return this;
294         }
295 
296         /**
297          * Disables the "Sign in to network" notification. Used if the network transport will
298          * perform its own carrier-specific provisioning procedure.
299          *
300          * @return this builder, to facilitate chaining.
301          * @hide
302          */
303         @NonNull
disableProvisioningNotification()304         public Builder disableProvisioningNotification() {
305             mConfig.provisioningNotificationDisabled = true;
306             return this;
307         }
308 
309         /**
310          * Sets the legacy type for this network.
311          *
312          * @param legacyType the type
313          * @return this builder, to facilitate chaining.
314          */
315         @NonNull
setLegacyType(int legacyType)316         public Builder setLegacyType(int legacyType) {
317             mConfig.legacyType = legacyType;
318             return this;
319         }
320 
321         /**
322          * Sets the name of the legacy type of the agent. It's a free-form string used in logging.
323          * @param legacyTypeName the name
324          * @return this builder, to facilitate chaining.
325          */
326         @NonNull
setLegacyTypeName(@onNull String legacyTypeName)327         public Builder setLegacyTypeName(@NonNull String legacyTypeName) {
328             mConfig.legacyTypeName = legacyTypeName;
329             return this;
330         }
331 
332         /**
333          * Sets the legacy extra info of the agent.
334          * @param legacyExtraInfo the legacy extra info.
335          * @return this builder, to facilitate chaining.
336          * @hide
337          */
338         @NonNull
setLegacyExtraInfo(@onNull String legacyExtraInfo)339         public Builder setLegacyExtraInfo(@NonNull String legacyExtraInfo) {
340             mConfig.mLegacyExtraInfo = legacyExtraInfo;
341             return this;
342         }
343 
344         /**
345          * Returns the constructed {@link NetworkAgentConfig} object.
346          */
347         @NonNull
build()348         public NetworkAgentConfig build() {
349             return mConfig;
350         }
351     }
352 
353     @Override
equals(final Object o)354     public boolean equals(final Object o) {
355         if (this == o) return true;
356         if (o == null || getClass() != o.getClass()) return false;
357         final NetworkAgentConfig that = (NetworkAgentConfig) o;
358         return allowBypass == that.allowBypass
359                 && explicitlySelected == that.explicitlySelected
360                 && acceptUnvalidated == that.acceptUnvalidated
361                 && acceptPartialConnectivity == that.acceptPartialConnectivity
362                 && provisioningNotificationDisabled == that.provisioningNotificationDisabled
363                 && skip464xlat == that.skip464xlat
364                 && legacyType == that.legacyType
365                 && Objects.equals(subscriberId, that.subscriberId)
366                 && Objects.equals(legacyTypeName, that.legacyTypeName)
367                 && Objects.equals(mLegacyExtraInfo, that.mLegacyExtraInfo);
368     }
369 
370     @Override
hashCode()371     public int hashCode() {
372         return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated,
373                 acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId,
374                 skip464xlat, legacyType, legacyTypeName, mLegacyExtraInfo);
375     }
376 
377     @Override
toString()378     public String toString() {
379         return "NetworkAgentConfig {"
380                 + " allowBypass = " + allowBypass
381                 + ", explicitlySelected = " + explicitlySelected
382                 + ", acceptUnvalidated = " + acceptUnvalidated
383                 + ", acceptPartialConnectivity = " + acceptPartialConnectivity
384                 + ", provisioningNotificationDisabled = " + provisioningNotificationDisabled
385                 + ", subscriberId = '" + subscriberId + '\''
386                 + ", skip464xlat = " + skip464xlat
387                 + ", legacyType = " + legacyType
388                 + ", hasShownBroken = " + hasShownBroken
389                 + ", legacyTypeName = '" + legacyTypeName + '\''
390                 + ", legacyExtraInfo = '" + mLegacyExtraInfo + '\''
391                 + "}";
392     }
393 
394     @Override
describeContents()395     public int describeContents() {
396         return 0;
397     }
398 
399     @Override
writeToParcel(@onNull Parcel out, int flags)400     public void writeToParcel(@NonNull Parcel out, int flags) {
401         out.writeInt(allowBypass ? 1 : 0);
402         out.writeInt(explicitlySelected ? 1 : 0);
403         out.writeInt(acceptUnvalidated ? 1 : 0);
404         out.writeInt(acceptPartialConnectivity ? 1 : 0);
405         out.writeString(subscriberId);
406         out.writeInt(provisioningNotificationDisabled ? 1 : 0);
407         out.writeInt(skip464xlat ? 1 : 0);
408         out.writeInt(legacyType);
409         out.writeString(legacyTypeName);
410         out.writeString(mLegacyExtraInfo);
411     }
412 
413     public static final @NonNull Creator<NetworkAgentConfig> CREATOR =
414             new Creator<NetworkAgentConfig>() {
415         @Override
416         public NetworkAgentConfig createFromParcel(Parcel in) {
417             NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig();
418             networkAgentConfig.allowBypass = in.readInt() != 0;
419             networkAgentConfig.explicitlySelected = in.readInt() != 0;
420             networkAgentConfig.acceptUnvalidated = in.readInt() != 0;
421             networkAgentConfig.acceptPartialConnectivity = in.readInt() != 0;
422             networkAgentConfig.subscriberId = in.readString();
423             networkAgentConfig.provisioningNotificationDisabled = in.readInt() != 0;
424             networkAgentConfig.skip464xlat = in.readInt() != 0;
425             networkAgentConfig.legacyType = in.readInt();
426             networkAgentConfig.legacyTypeName = in.readString();
427             networkAgentConfig.mLegacyExtraInfo = in.readString();
428             return networkAgentConfig;
429         }
430 
431         @Override
432         public NetworkAgentConfig[] newArray(int size) {
433             return new NetworkAgentConfig[size];
434         }
435     };
436 }
437