1 /*
2  * Copyright (C) 2021 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.vcn;
18 
19 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
20 import static android.net.vcn.VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET;
21 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
22 
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.net.NetworkCapabilities;
26 import android.net.TransportInfo;
27 import android.net.wifi.WifiInfo;
28 import android.os.Parcel;
29 import android.os.Parcelable;
30 import android.telephony.SubscriptionManager;
31 
32 import java.util.Objects;
33 
34 /**
35  * VcnTransportInfo contains information about the VCN's underlying transports for SysUi.
36  *
37  * <p>Presence of this class in the NetworkCapabilities.TransportInfo implies that the network is a
38  * VCN.
39  *
40  * <p>VcnTransportInfo must exist on top of either an underlying Wifi or Cellular Network. If the
41  * underlying Network is WiFi, the subId will be {@link
42  * SubscriptionManager#INVALID_SUBSCRIPTION_ID}. If the underlying Network is Cellular, the WifiInfo
43  * will be {@code null}.
44  *
45  * <p>Receipt of a VcnTransportInfo requires the NETWORK_SETTINGS permission; else the entire
46  * VcnTransportInfo instance will be redacted.
47  *
48  * @hide
49  */
50 public class VcnTransportInfo implements TransportInfo, Parcelable {
51     @Nullable private final WifiInfo mWifiInfo;
52     private final int mSubId;
53     private final int mMinUdpPort4500NatTimeoutSeconds;
54 
VcnTransportInfo(@onNull WifiInfo wifiInfo)55     public VcnTransportInfo(@NonNull WifiInfo wifiInfo) {
56         this(wifiInfo, INVALID_SUBSCRIPTION_ID, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
57     }
58 
VcnTransportInfo(@onNull WifiInfo wifiInfo, int minUdpPort4500NatTimeoutSeconds)59     public VcnTransportInfo(@NonNull WifiInfo wifiInfo, int minUdpPort4500NatTimeoutSeconds) {
60         this(wifiInfo, INVALID_SUBSCRIPTION_ID, minUdpPort4500NatTimeoutSeconds);
61     }
62 
VcnTransportInfo(int subId)63     public VcnTransportInfo(int subId) {
64         this(null /* wifiInfo */, subId, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
65     }
66 
VcnTransportInfo(int subId, int minUdpPort4500NatTimeoutSeconds)67     public VcnTransportInfo(int subId, int minUdpPort4500NatTimeoutSeconds) {
68         this(null /* wifiInfo */, subId, minUdpPort4500NatTimeoutSeconds);
69     }
70 
VcnTransportInfo( @ullable WifiInfo wifiInfo, int subId, int minUdpPort4500NatTimeoutSeconds)71     private VcnTransportInfo(
72             @Nullable WifiInfo wifiInfo, int subId, int minUdpPort4500NatTimeoutSeconds) {
73         mWifiInfo = wifiInfo;
74         mSubId = subId;
75         mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds;
76     }
77 
78     /**
79      * Get the {@link WifiInfo} for this VcnTransportInfo.
80      *
81      * <p>If the underlying Network for the associated VCN is Cellular, returns null.
82      *
83      * @return the WifiInfo if there is an underlying WiFi connection, else null.
84      */
85     @Nullable
getWifiInfo()86     public WifiInfo getWifiInfo() {
87         return mWifiInfo;
88     }
89 
90     /**
91      * Get the subId for the VCN Network associated with this VcnTransportInfo.
92      *
93      * <p>If the underlying Network for the associated VCN is WiFi, returns {@link
94      * SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
95      *
96      * @return the Subscription ID if a cellular underlying Network is present, else {@link
97      *     android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
98      */
getSubId()99     public int getSubId() {
100         return mSubId;
101     }
102 
103     /**
104      * Get the VCN provided UDP port 4500 NAT timeout
105      *
106      * @return the UDP 4500 NAT timeout, or
107      *     VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET if not set.
108      */
getMinUdpPort4500NatTimeoutSeconds()109     public int getMinUdpPort4500NatTimeoutSeconds() {
110         return mMinUdpPort4500NatTimeoutSeconds;
111     }
112 
113     @Override
hashCode()114     public int hashCode() {
115         return Objects.hash(mWifiInfo, mSubId, mMinUdpPort4500NatTimeoutSeconds);
116     }
117 
118     @Override
equals(Object o)119     public boolean equals(Object o) {
120         if (!(o instanceof VcnTransportInfo)) return false;
121         final VcnTransportInfo that = (VcnTransportInfo) o;
122         return Objects.equals(mWifiInfo, that.mWifiInfo)
123                 && mSubId == that.mSubId
124                 && mMinUdpPort4500NatTimeoutSeconds == that.mMinUdpPort4500NatTimeoutSeconds;
125     }
126 
127     /** {@inheritDoc} */
128     @Override
describeContents()129     public int describeContents() {
130         return 0;
131     }
132 
133     @Override
134     @NonNull
makeCopy(long redactions)135     public TransportInfo makeCopy(long redactions) {
136         if ((redactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) != 0) {
137             return new VcnTransportInfo(
138                     null, INVALID_SUBSCRIPTION_ID, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
139         }
140 
141         return new VcnTransportInfo(
142                 (mWifiInfo == null) ? null : mWifiInfo.makeCopy(redactions),
143                 mSubId,
144                 mMinUdpPort4500NatTimeoutSeconds);
145     }
146 
147     @Override
getApplicableRedactions()148     public long getApplicableRedactions() {
149         long redactions = REDACT_FOR_NETWORK_SETTINGS;
150 
151         // Add additional wifi redactions if necessary
152         if (mWifiInfo != null) {
153             redactions |= mWifiInfo.getApplicableRedactions();
154         }
155 
156         return redactions;
157     }
158 
159     /** {@inheritDoc} */
160     @Override
writeToParcel(@onNull Parcel dest, int flags)161     public void writeToParcel(@NonNull Parcel dest, int flags) {
162         dest.writeInt(mSubId);
163         dest.writeParcelable(mWifiInfo, flags);
164         dest.writeInt(mMinUdpPort4500NatTimeoutSeconds);
165     }
166 
167     @Override
toString()168     public String toString() {
169         return "VcnTransportInfo { mWifiInfo = " + mWifiInfo + ", mSubId = " + mSubId + " }";
170     }
171 
172     /** Implement the Parcelable interface */
173     public static final @NonNull Creator<VcnTransportInfo> CREATOR =
174             new Creator<VcnTransportInfo>() {
175                 public VcnTransportInfo createFromParcel(Parcel in) {
176                     final int subId = in.readInt();
177                     final WifiInfo wifiInfo =
178                             in.readParcelable(null, android.net.wifi.WifiInfo.class);
179                     final int minUdpPort4500NatTimeoutSeconds = in.readInt();
180 
181                     // If all fields are their null values, return null TransportInfo to avoid
182                     // leaking information about this being a VCN Network (instead of macro
183                     // cellular, etc)
184                     if (wifiInfo == null
185                             && subId == INVALID_SUBSCRIPTION_ID
186                             && minUdpPort4500NatTimeoutSeconds
187                                     == MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET) {
188                         return null;
189                     }
190 
191                     return new VcnTransportInfo(wifiInfo, subId, minUdpPort4500NatTimeoutSeconds);
192                 }
193 
194                 public VcnTransportInfo[] newArray(int size) {
195                     return new VcnTransportInfo[size];
196                 }
197             };
198 }
199