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