• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.SystemApi;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 
27 import com.android.modules.utils.build.SdkLevel;
28 
29 import java.util.Objects;
30 
31 /**
32  * Allows a network transport to provide the system with policy and configuration information about
33  * a particular network when registering a {@link NetworkAgent}. This information cannot change once the agent is registered.
34  *
35  * @hide
36  */
37 @SystemApi
38 public final class NetworkAgentConfig implements Parcelable {
39     // TODO : make this object immutable. The fields that should stay mutable should likely
40     // migrate to NetworkAgentInfo.
41 
42     /**
43      * If the {@link Network} is a VPN, whether apps are allowed to bypass the
44      * VPN. This is set by a {@link VpnService} and used by
45      * {@link ConnectivityManager} when creating a VPN.
46      *
47      * @hide
48      */
49     public boolean allowBypass;
50 
51     /**
52      * Set if the network was manually/explicitly connected to by the user either from settings
53      * or a 3rd party app.  For example, turning on cell data is not explicit but tapping on a wifi
54      * ap in the wifi settings to trigger a connection is explicit.  A 3rd party app asking to
55      * connect to a particular access point is also explicit, though this may change in the future
56      * as we want apps to use the multinetwork apis.
57      * TODO : this is a bad name, because it sounds like the user just tapped on the network.
58      * It's not necessarily the case ; auto-reconnection to WiFi has this true for example.
59      * @hide
60      */
61     public boolean explicitlySelected;
62 
63     /**
64      * @return whether this network was explicitly selected by the user.
65      */
isExplicitlySelected()66     public boolean isExplicitlySelected() {
67         return explicitlySelected;
68     }
69 
70     /**
71      * @return whether this VPN connection can be bypassed by the apps.
72      *
73      * @hide
74      */
75     @SystemApi(client = MODULE_LIBRARIES)
isBypassableVpn()76     public boolean isBypassableVpn() {
77         return allowBypass;
78     }
79 
80     /**
81      * Set if the user desires to use this network even if it is unvalidated. This field has meaning
82      * only if {@link explicitlySelected} is true. If it is, this field must also be set to the
83      * appropriate value based on previous user choice.
84      *
85      * TODO : rename this field to match its accessor
86      * @hide
87      */
88     public boolean acceptUnvalidated;
89 
90     /**
91      * @return whether the system should accept this network even if it doesn't validate.
92      */
isUnvalidatedConnectivityAcceptable()93     public boolean isUnvalidatedConnectivityAcceptable() {
94         return acceptUnvalidated;
95     }
96 
97     /**
98      * Whether the user explicitly set that this network should be validated even if presence of
99      * only partial internet connectivity.
100      *
101      * TODO : rename this field to match its accessor
102      * @hide
103      */
104     public boolean acceptPartialConnectivity;
105 
106     /**
107      * @return whether the system should validate this network even if it only offers partial
108      *     Internet connectivity.
109      */
isPartialConnectivityAcceptable()110     public boolean isPartialConnectivityAcceptable() {
111         return acceptPartialConnectivity;
112     }
113 
114     /**
115      * Set to avoid surfacing the "Sign in to network" notification.
116      * if carrier receivers/apps are registered to handle the carrier-specific provisioning
117      * procedure, a carrier specific provisioning notification will be placed.
118      * only one notification should be displayed. This field is set based on
119      * which notification should be used for provisioning.
120      *
121      * @hide
122      */
123     public boolean provisioningNotificationDisabled;
124 
125     /**
126      *
127      * @return whether the sign in to network notification is enabled by this configuration.
128      * @hide
129      */
isProvisioningNotificationEnabled()130     public boolean isProvisioningNotificationEnabled() {
131         return !provisioningNotificationDisabled;
132     }
133 
134     /**
135      * For mobile networks, this is the subscriber ID (such as IMSI).
136      *
137      * @hide
138      */
139     public String subscriberId;
140 
141     /**
142      * @return the subscriber ID, or null if none.
143      * @hide
144      */
145     @SystemApi(client = MODULE_LIBRARIES)
146     @Nullable
getSubscriberId()147     public String getSubscriberId() {
148         return subscriberId;
149     }
150 
151     /**
152      * Set to skip 464xlat. This means the device will treat the network as IPv6-only and
153      * will not attempt to detect a NAT64 via RFC 7050 DNS lookups.
154      *
155      * @hide
156      */
157     public boolean skip464xlat;
158 
159     /**
160      * @return whether NAT64 prefix detection is enabled.
161      * @hide
162      */
isNat64DetectionEnabled()163     public boolean isNat64DetectionEnabled() {
164         return !skip464xlat;
165     }
166 
167     /**
168      * The legacy type of this network agent, or TYPE_NONE if unset.
169      * @hide
170      */
171     public int legacyType = ConnectivityManager.TYPE_NONE;
172 
173     /**
174      * @return the legacy type
175      */
176     @ConnectivityManager.LegacyNetworkType
getLegacyType()177     public int getLegacyType() {
178         return legacyType;
179     }
180 
181     /**
182      * The legacy Sub type of this network agent, or TYPE_NONE if unset.
183      * @hide
184      */
185     public int legacySubType = ConnectivityManager.TYPE_NONE;
186 
187     /**
188      * Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network.
189      * Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode.
190      *
191      * This is not parceled, because it would not make sense.
192      *
193      * @hide
194      */
195     public transient boolean hasShownBroken;
196 
197     /**
198      * The name of the legacy network type. It's a free-form string used in logging.
199      * @hide
200      */
201     @NonNull
202     public String legacyTypeName = "";
203 
204     /**
205      * @return the name of the legacy network type. It's a free-form string used in logging.
206      */
207     @NonNull
getLegacyTypeName()208     public String getLegacyTypeName() {
209         return legacyTypeName;
210     }
211 
212     /**
213      * The name of the legacy Sub network type. It's a free-form string.
214      * @hide
215      */
216     @NonNull
217     public String legacySubTypeName = "";
218 
219     /**
220      * The legacy extra info of the agent. The extra info should only be :
221      * <ul>
222      *   <li>For cellular agents, the APN name.</li>
223      *   <li>For ethernet agents, the interface name.</li>
224      * </ul>
225      * @hide
226      */
227     @NonNull
228     private String mLegacyExtraInfo = "";
229 
230     /**
231      * The legacy extra info of the agent.
232      * @hide
233      */
234     @NonNull
getLegacyExtraInfo()235     public String getLegacyExtraInfo() {
236         return mLegacyExtraInfo;
237     }
238 
239     /**
240      * If the {@link Network} is a VPN, whether the local traffic is exempted from the VPN.
241      * @hide
242      */
243     public boolean excludeLocalRouteVpn = false;
244 
245     /**
246      * @return whether local traffic is excluded from the VPN network.
247      * @hide
248      */
areLocalRoutesExcludedForVpn()249     public boolean areLocalRoutesExcludedForVpn() {
250         return excludeLocalRouteVpn;
251     }
252 
253     /**
254      * Whether network validation should be performed for this VPN network.
255      * {@see #isVpnValidationRequired}
256      * @hide
257      */
258     private boolean mVpnRequiresValidation = false;
259 
260     /**
261      * Whether network validation should be performed for this VPN network.
262      *
263      * If this network isn't a VPN this should always be {@code false}, and will be ignored
264      * if set.
265      * If this network is a VPN, false means this network should always be considered validated;
266      * true means it follows the same validation semantics as general internet networks.
267      * @hide
268      */
269     @SystemApi(client = MODULE_LIBRARIES)
isVpnValidationRequired()270     public boolean isVpnValidationRequired() {
271         return mVpnRequiresValidation;
272     }
273 
274     /** @hide */
NetworkAgentConfig()275     public NetworkAgentConfig() {
276     }
277 
278     /** @hide */
NetworkAgentConfig(@ullable NetworkAgentConfig nac)279     public NetworkAgentConfig(@Nullable NetworkAgentConfig nac) {
280         if (nac != null) {
281             allowBypass = nac.allowBypass;
282             explicitlySelected = nac.explicitlySelected;
283             acceptUnvalidated = nac.acceptUnvalidated;
284             acceptPartialConnectivity = nac.acceptPartialConnectivity;
285             subscriberId = nac.subscriberId;
286             provisioningNotificationDisabled = nac.provisioningNotificationDisabled;
287             skip464xlat = nac.skip464xlat;
288             legacyType = nac.legacyType;
289             legacyTypeName = nac.legacyTypeName;
290             legacySubType = nac.legacySubType;
291             legacySubTypeName = nac.legacySubTypeName;
292             mLegacyExtraInfo = nac.mLegacyExtraInfo;
293             excludeLocalRouteVpn = nac.excludeLocalRouteVpn;
294             mVpnRequiresValidation = nac.mVpnRequiresValidation;
295         }
296     }
297 
298     /**
299      * Builder class to facilitate constructing {@link NetworkAgentConfig} objects.
300      */
301     public static final class Builder {
302         private final NetworkAgentConfig mConfig = new NetworkAgentConfig();
303 
304         /**
305          * Sets whether the network was explicitly selected by the user.
306          *
307          * @return this builder, to facilitate chaining.
308          */
309         @NonNull
setExplicitlySelected(final boolean explicitlySelected)310         public Builder setExplicitlySelected(final boolean explicitlySelected) {
311             mConfig.explicitlySelected = explicitlySelected;
312             return this;
313         }
314 
315         /**
316          * Sets whether the system should validate this network even if it is found not to offer
317          * Internet connectivity.
318          *
319          * @return this builder, to facilitate chaining.
320          */
321         @NonNull
setUnvalidatedConnectivityAcceptable( final boolean unvalidatedConnectivityAcceptable)322         public Builder setUnvalidatedConnectivityAcceptable(
323                 final boolean unvalidatedConnectivityAcceptable) {
324             mConfig.acceptUnvalidated = unvalidatedConnectivityAcceptable;
325             return this;
326         }
327 
328         /**
329          * Sets whether the system should validate this network even if it is found to only offer
330          * partial Internet connectivity.
331          *
332          * @return this builder, to facilitate chaining.
333          */
334         @NonNull
setPartialConnectivityAcceptable( final boolean partialConnectivityAcceptable)335         public Builder setPartialConnectivityAcceptable(
336                 final boolean partialConnectivityAcceptable) {
337             mConfig.acceptPartialConnectivity = partialConnectivityAcceptable;
338             return this;
339         }
340 
341         /**
342          * Sets the subscriber ID for this network.
343          *
344          * @return this builder, to facilitate chaining.
345          * @hide
346          */
347         @NonNull
348         @SystemApi(client = MODULE_LIBRARIES)
setSubscriberId(@ullable String subscriberId)349         public Builder setSubscriberId(@Nullable String subscriberId) {
350             mConfig.subscriberId = subscriberId;
351             return this;
352         }
353 
354         /**
355          * Enables or disables active detection of NAT64 (e.g., via RFC 7050 DNS lookups). Used to
356          * save power and reduce idle traffic on networks that are known to be IPv6-only without a
357          * NAT64. By default, NAT64 detection is enabled.
358          *
359          * @return this builder, to facilitate chaining.
360          */
361         @NonNull
setNat64DetectionEnabled(boolean enabled)362         public Builder setNat64DetectionEnabled(boolean enabled) {
363             mConfig.skip464xlat = !enabled;
364             return this;
365         }
366 
367         /**
368          * Enables or disables the "Sign in to network" notification. Used if the network transport
369          * will perform its own carrier-specific provisioning procedure. By default, the
370          * notification is enabled.
371          *
372          * @return this builder, to facilitate chaining.
373          */
374         @NonNull
setProvisioningNotificationEnabled(boolean enabled)375         public Builder setProvisioningNotificationEnabled(boolean enabled) {
376             mConfig.provisioningNotificationDisabled = !enabled;
377             return this;
378         }
379 
380         /**
381          * Sets the legacy type for this network.
382          *
383          * @param legacyType the type
384          * @return this builder, to facilitate chaining.
385          */
386         @NonNull
setLegacyType(int legacyType)387         public Builder setLegacyType(int legacyType) {
388             mConfig.legacyType = legacyType;
389             return this;
390         }
391 
392         /**
393          * Sets the legacy sub-type for this network.
394          *
395          * @param legacySubType the type
396          * @return this builder, to facilitate chaining.
397          */
398         @NonNull
setLegacySubType(final int legacySubType)399         public Builder setLegacySubType(final int legacySubType) {
400             mConfig.legacySubType = legacySubType;
401             return this;
402         }
403 
404         /**
405          * Sets the name of the legacy type of the agent. It's a free-form string used in logging.
406          * @param legacyTypeName the name
407          * @return this builder, to facilitate chaining.
408          */
409         @NonNull
setLegacyTypeName(@onNull String legacyTypeName)410         public Builder setLegacyTypeName(@NonNull String legacyTypeName) {
411             mConfig.legacyTypeName = legacyTypeName;
412             return this;
413         }
414 
415         /**
416          * Sets the name of the legacy Sub-type of the agent. It's a free-form string.
417          * @param legacySubTypeName the name
418          * @return this builder, to facilitate chaining.
419          */
420         @NonNull
setLegacySubTypeName(@onNull String legacySubTypeName)421         public Builder setLegacySubTypeName(@NonNull String legacySubTypeName) {
422             mConfig.legacySubTypeName = legacySubTypeName;
423             return this;
424         }
425 
426         /**
427          * Sets the legacy extra info of the agent.
428          * @param legacyExtraInfo the legacy extra info.
429          * @return this builder, to facilitate chaining.
430          */
431         @NonNull
setLegacyExtraInfo(@onNull String legacyExtraInfo)432         public Builder setLegacyExtraInfo(@NonNull String legacyExtraInfo) {
433             mConfig.mLegacyExtraInfo = legacyExtraInfo;
434             return this;
435         }
436 
437         /**
438          * Sets whether network validation should be performed for this VPN network.
439          *
440          * Only agents registering a VPN network should use this setter. On other network
441          * types it will be ignored.
442          * False means this network should always be considered validated;
443          * true means it follows the same validation semantics as general internet.
444          *
445          * @param vpnRequiresValidation whether this VPN requires validation.
446          *                              Default is {@code false}.
447          * @hide
448          */
449         @NonNull
450         @SystemApi(client = MODULE_LIBRARIES)
setVpnRequiresValidation(boolean vpnRequiresValidation)451         public Builder setVpnRequiresValidation(boolean vpnRequiresValidation) {
452             mConfig.mVpnRequiresValidation = vpnRequiresValidation;
453             return this;
454         }
455 
456         /**
457          * Sets whether the apps can bypass the VPN connection.
458          *
459          * @return this builder, to facilitate chaining.
460          * @hide
461          */
462         @NonNull
463         @SystemApi(client = MODULE_LIBRARIES)
setBypassableVpn(boolean allowBypass)464         public Builder setBypassableVpn(boolean allowBypass) {
465             mConfig.allowBypass = allowBypass;
466             return this;
467         }
468 
469         /**
470          * Sets whether the local traffic is exempted from VPN.
471          *
472          * @return this builder, to facilitate chaining.
473          * @hide
474          */
475         @NonNull
476         @SystemApi(client = MODULE_LIBRARIES)
setLocalRoutesExcludedForVpn(boolean excludeLocalRoutes)477         public Builder setLocalRoutesExcludedForVpn(boolean excludeLocalRoutes) {
478             if (!SdkLevel.isAtLeastT()) {
479                 throw new UnsupportedOperationException("Method is not supported");
480             }
481             mConfig.excludeLocalRouteVpn = excludeLocalRoutes;
482             return this;
483         }
484 
485         /**
486          * Returns the constructed {@link NetworkAgentConfig} object.
487          */
488         @NonNull
build()489         public NetworkAgentConfig build() {
490             return mConfig;
491         }
492     }
493 
494     @Override
equals(final Object o)495     public boolean equals(final Object o) {
496         if (this == o) return true;
497         if (o == null || getClass() != o.getClass()) return false;
498         final NetworkAgentConfig that = (NetworkAgentConfig) o;
499         return allowBypass == that.allowBypass
500                 && explicitlySelected == that.explicitlySelected
501                 && acceptUnvalidated == that.acceptUnvalidated
502                 && acceptPartialConnectivity == that.acceptPartialConnectivity
503                 && provisioningNotificationDisabled == that.provisioningNotificationDisabled
504                 && skip464xlat == that.skip464xlat
505                 && legacyType == that.legacyType
506                 && Objects.equals(subscriberId, that.subscriberId)
507                 && Objects.equals(legacyTypeName, that.legacyTypeName)
508                 && Objects.equals(mLegacyExtraInfo, that.mLegacyExtraInfo)
509                 && excludeLocalRouteVpn == that.excludeLocalRouteVpn
510                 && mVpnRequiresValidation == that.mVpnRequiresValidation;
511     }
512 
513     @Override
hashCode()514     public int hashCode() {
515         return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated,
516                 acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId,
517                 skip464xlat, legacyType, legacyTypeName, mLegacyExtraInfo, excludeLocalRouteVpn,
518                 mVpnRequiresValidation);
519     }
520 
521     @Override
toString()522     public String toString() {
523         return "NetworkAgentConfig {"
524                 + " allowBypass = " + allowBypass
525                 + ", explicitlySelected = " + explicitlySelected
526                 + ", acceptUnvalidated = " + acceptUnvalidated
527                 + ", acceptPartialConnectivity = " + acceptPartialConnectivity
528                 + ", provisioningNotificationDisabled = " + provisioningNotificationDisabled
529                 + ", subscriberId = '" + subscriberId + '\''
530                 + ", skip464xlat = " + skip464xlat
531                 + ", legacyType = " + legacyType
532                 + ", hasShownBroken = " + hasShownBroken
533                 + ", legacyTypeName = '" + legacyTypeName + '\''
534                 + ", legacyExtraInfo = '" + mLegacyExtraInfo + '\''
535                 + ", excludeLocalRouteVpn = '" + excludeLocalRouteVpn + '\''
536                 + ", vpnRequiresValidation = '" + mVpnRequiresValidation + '\''
537                 + "}";
538     }
539 
540     @Override
describeContents()541     public int describeContents() {
542         return 0;
543     }
544 
545     @Override
writeToParcel(@onNull Parcel out, int flags)546     public void writeToParcel(@NonNull Parcel out, int flags) {
547         out.writeInt(allowBypass ? 1 : 0);
548         out.writeInt(explicitlySelected ? 1 : 0);
549         out.writeInt(acceptUnvalidated ? 1 : 0);
550         out.writeInt(acceptPartialConnectivity ? 1 : 0);
551         out.writeString(subscriberId);
552         out.writeInt(provisioningNotificationDisabled ? 1 : 0);
553         out.writeInt(skip464xlat ? 1 : 0);
554         out.writeInt(legacyType);
555         out.writeString(legacyTypeName);
556         out.writeInt(legacySubType);
557         out.writeString(legacySubTypeName);
558         out.writeString(mLegacyExtraInfo);
559         out.writeInt(excludeLocalRouteVpn ? 1 : 0);
560         out.writeInt(mVpnRequiresValidation ? 1 : 0);
561     }
562 
563     public static final @NonNull Creator<NetworkAgentConfig> CREATOR =
564             new Creator<NetworkAgentConfig>() {
565         @Override
566         public NetworkAgentConfig createFromParcel(Parcel in) {
567             NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig();
568             networkAgentConfig.allowBypass = in.readInt() != 0;
569             networkAgentConfig.explicitlySelected = in.readInt() != 0;
570             networkAgentConfig.acceptUnvalidated = in.readInt() != 0;
571             networkAgentConfig.acceptPartialConnectivity = in.readInt() != 0;
572             networkAgentConfig.subscriberId = in.readString();
573             networkAgentConfig.provisioningNotificationDisabled = in.readInt() != 0;
574             networkAgentConfig.skip464xlat = in.readInt() != 0;
575             networkAgentConfig.legacyType = in.readInt();
576             networkAgentConfig.legacyTypeName = in.readString();
577             networkAgentConfig.legacySubType = in.readInt();
578             networkAgentConfig.legacySubTypeName = in.readString();
579             networkAgentConfig.mLegacyExtraInfo = in.readString();
580             networkAgentConfig.excludeLocalRouteVpn = in.readInt() != 0;
581             networkAgentConfig.mVpnRequiresValidation = in.readInt() != 0;
582             return networkAgentConfig;
583         }
584 
585         @Override
586         public NetworkAgentConfig[] newArray(int size) {
587             return new NetworkAgentConfig[size];
588         }
589     };
590 }
591