diff options
Diffstat (limited to 'core/java/android')
74 files changed, 0 insertions, 23015 deletions
diff --git a/core/java/android/net/CaptivePortal.java b/core/java/android/net/CaptivePortal.java deleted file mode 100644 index 269bbf20c8b1..000000000000 --- a/core/java/android/net/CaptivePortal.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed urnder the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net; - -import android.annotation.NonNull; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.os.IBinder; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.RemoteException; - -/** - * A class allowing apps handling the {@link ConnectivityManager#ACTION_CAPTIVE_PORTAL_SIGN_IN} - * activity to indicate to the system different outcomes of captive portal sign in. This class is - * passed as an extra named {@link ConnectivityManager#EXTRA_CAPTIVE_PORTAL} with the - * {@code ACTION_CAPTIVE_PORTAL_SIGN_IN} activity. - */ -public class CaptivePortal implements Parcelable { - /** - * Response code from the captive portal application, indicating that the portal was dismissed - * and the network should be re-validated. - * @see ICaptivePortal#appResponse(int) - * @see android.net.INetworkMonitor#notifyCaptivePortalAppFinished(int) - * @hide - */ - @SystemApi - public static final int APP_RETURN_DISMISSED = 0; - /** - * Response code from the captive portal application, indicating that the user did not login and - * does not want to use the captive portal network. - * @see ICaptivePortal#appResponse(int) - * @see android.net.INetworkMonitor#notifyCaptivePortalAppFinished(int) - * @hide - */ - @SystemApi - public static final int APP_RETURN_UNWANTED = 1; - /** - * Response code from the captive portal application, indicating that the user does not wish to - * login but wants to use the captive portal network as-is. - * @see ICaptivePortal#appResponse(int) - * @see android.net.INetworkMonitor#notifyCaptivePortalAppFinished(int) - * @hide - */ - @SystemApi - public static final int APP_RETURN_WANTED_AS_IS = 2; - /** Event offset of request codes from captive portal application. */ - private static final int APP_REQUEST_BASE = 100; - /** - * Request code from the captive portal application, indicating that the network condition may - * have changed and the network should be re-validated. - * @see ICaptivePortal#appRequest(int) - * @see android.net.INetworkMonitor#forceReevaluation(int) - * @hide - */ - @SystemApi - public static final int APP_REQUEST_REEVALUATION_REQUIRED = APP_REQUEST_BASE + 0; - - private final IBinder mBinder; - - /** @hide */ - public CaptivePortal(@NonNull IBinder binder) { - mBinder = binder; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeStrongBinder(mBinder); - } - - public static final @android.annotation.NonNull Parcelable.Creator<CaptivePortal> CREATOR - = new Parcelable.Creator<CaptivePortal>() { - @Override - public CaptivePortal createFromParcel(Parcel in) { - return new CaptivePortal(in.readStrongBinder()); - } - - @Override - public CaptivePortal[] newArray(int size) { - return new CaptivePortal[size]; - } - }; - - /** - * Indicate to the system that the captive portal has been - * dismissed. In response the framework will re-evaluate the network's - * connectivity and might take further action thereafter. - */ - public void reportCaptivePortalDismissed() { - try { - ICaptivePortal.Stub.asInterface(mBinder).appResponse(APP_RETURN_DISMISSED); - } catch (RemoteException e) { - } - } - - /** - * Indicate to the system that the user does not want to pursue signing in to the - * captive portal and the system should continue to prefer other networks - * without captive portals for use as the default active data network. The - * system will not retest the network for a captive portal so as to avoid - * disturbing the user with further sign in to network notifications. - */ - public void ignoreNetwork() { - try { - ICaptivePortal.Stub.asInterface(mBinder).appResponse(APP_RETURN_UNWANTED); - } catch (RemoteException e) { - } - } - - /** - * Indicate to the system the user wants to use this network as is, even though - * the captive portal is still in place. The system will treat the network - * as if it did not have a captive portal when selecting the network to use - * as the default active data network. This may result in this network - * becoming the default active data network, which could disrupt network - * connectivity for apps because the captive portal is still in place. - * @hide - */ - @SystemApi - public void useNetwork() { - try { - ICaptivePortal.Stub.asInterface(mBinder).appResponse(APP_RETURN_WANTED_AS_IS); - } catch (RemoteException e) { - } - } - - /** - * Request that the system reevaluates the captive portal status. - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.NETWORK_STACK) - public void reevaluateNetwork() { - try { - ICaptivePortal.Stub.asInterface(mBinder).appRequest(APP_REQUEST_REEVALUATION_REQUIRED); - } catch (RemoteException e) { - } - } - - /** - * Log a captive portal login event. - * @param eventId one of the CAPTIVE_PORTAL_LOGIN_* constants in metrics_constants.proto. - * @param packageName captive portal application package name. - * @hide - */ - @SystemApi - public void logEvent(int eventId, @NonNull String packageName) { - try { - ICaptivePortal.Stub.asInterface(mBinder).logEvent(eventId, packageName); - } catch (RemoteException e) { - } - } -} diff --git a/core/java/android/net/CaptivePortalData.aidl b/core/java/android/net/CaptivePortalData.aidl deleted file mode 100644 index 1d57ee759136..000000000000 --- a/core/java/android/net/CaptivePortalData.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -@JavaOnlyStableParcelable parcelable CaptivePortalData; diff --git a/core/java/android/net/CaptivePortalData.java b/core/java/android/net/CaptivePortalData.java deleted file mode 100644 index 18467fad8ec4..000000000000 --- a/core/java/android/net/CaptivePortalData.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Objects; - -/** - * Metadata sent by captive portals, see https://www.ietf.org/id/draft-ietf-capport-api-03.txt. - * @hide - */ -@SystemApi -public final class CaptivePortalData implements Parcelable { - private final long mRefreshTimeMillis; - @Nullable - private final Uri mUserPortalUrl; - @Nullable - private final Uri mVenueInfoUrl; - private final boolean mIsSessionExtendable; - private final long mByteLimit; - private final long mExpiryTimeMillis; - private final boolean mCaptive; - private final String mVenueFriendlyName; - - private CaptivePortalData(long refreshTimeMillis, Uri userPortalUrl, Uri venueInfoUrl, - boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive, - String venueFriendlyName) { - mRefreshTimeMillis = refreshTimeMillis; - mUserPortalUrl = userPortalUrl; - mVenueInfoUrl = venueInfoUrl; - mIsSessionExtendable = isSessionExtendable; - mByteLimit = byteLimit; - mExpiryTimeMillis = expiryTimeMillis; - mCaptive = captive; - mVenueFriendlyName = venueFriendlyName; - } - - private CaptivePortalData(Parcel p) { - this(p.readLong(), p.readParcelable(null), p.readParcelable(null), p.readBoolean(), - p.readLong(), p.readLong(), p.readBoolean(), p.readString()); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeLong(mRefreshTimeMillis); - dest.writeParcelable(mUserPortalUrl, 0); - dest.writeParcelable(mVenueInfoUrl, 0); - dest.writeBoolean(mIsSessionExtendable); - dest.writeLong(mByteLimit); - dest.writeLong(mExpiryTimeMillis); - dest.writeBoolean(mCaptive); - dest.writeString(mVenueFriendlyName); - } - - /** - * A builder to create new {@link CaptivePortalData}. - */ - public static class Builder { - private long mRefreshTime; - private Uri mUserPortalUrl; - private Uri mVenueInfoUrl; - private boolean mIsSessionExtendable; - private long mBytesRemaining = -1; - private long mExpiryTime = -1; - private boolean mCaptive; - private String mVenueFriendlyName; - - /** - * Create an empty builder. - */ - public Builder() {} - - /** - * Create a builder copying all data from existing {@link CaptivePortalData}. - */ - public Builder(@Nullable CaptivePortalData data) { - if (data == null) return; - setRefreshTime(data.mRefreshTimeMillis) - .setUserPortalUrl(data.mUserPortalUrl) - .setVenueInfoUrl(data.mVenueInfoUrl) - .setSessionExtendable(data.mIsSessionExtendable) - .setBytesRemaining(data.mByteLimit) - .setExpiryTime(data.mExpiryTimeMillis) - .setCaptive(data.mCaptive) - .setVenueFriendlyName(data.mVenueFriendlyName); - } - - /** - * Set the time at which data was last refreshed, as per {@link System#currentTimeMillis()}. - */ - @NonNull - public Builder setRefreshTime(long refreshTime) { - mRefreshTime = refreshTime; - return this; - } - - /** - * Set the URL to be used for users to login to the portal, if captive. - */ - @NonNull - public Builder setUserPortalUrl(@Nullable Uri userPortalUrl) { - mUserPortalUrl = userPortalUrl; - return this; - } - - /** - * Set the URL that can be used by users to view information about the network venue. - */ - @NonNull - public Builder setVenueInfoUrl(@Nullable Uri venueInfoUrl) { - mVenueInfoUrl = venueInfoUrl; - return this; - } - - /** - * Set whether the portal supports extending a user session on the portal URL page. - */ - @NonNull - public Builder setSessionExtendable(boolean sessionExtendable) { - mIsSessionExtendable = sessionExtendable; - return this; - } - - /** - * Set the number of bytes remaining on the network before the portal closes. - */ - @NonNull - public Builder setBytesRemaining(long bytesRemaining) { - mBytesRemaining = bytesRemaining; - return this; - } - - /** - * Set the time at the session will expire, as per {@link System#currentTimeMillis()}. - */ - @NonNull - public Builder setExpiryTime(long expiryTime) { - mExpiryTime = expiryTime; - return this; - } - - /** - * Set whether the network is captive (portal closed). - */ - @NonNull - public Builder setCaptive(boolean captive) { - mCaptive = captive; - return this; - } - - /** - * Set the venue friendly name. - */ - @NonNull - public Builder setVenueFriendlyName(@Nullable String venueFriendlyName) { - mVenueFriendlyName = venueFriendlyName; - return this; - } - - /** - * Create a new {@link CaptivePortalData}. - */ - @NonNull - public CaptivePortalData build() { - return new CaptivePortalData(mRefreshTime, mUserPortalUrl, mVenueInfoUrl, - mIsSessionExtendable, mBytesRemaining, mExpiryTime, mCaptive, - mVenueFriendlyName); - } - } - - /** - * Get the time at which data was last refreshed, as per {@link System#currentTimeMillis()}. - */ - public long getRefreshTimeMillis() { - return mRefreshTimeMillis; - } - - /** - * Get the URL to be used for users to login to the portal, or extend their session if - * {@link #isSessionExtendable()} is true. - */ - @Nullable - public Uri getUserPortalUrl() { - return mUserPortalUrl; - } - - /** - * Get the URL that can be used by users to view information about the network venue. - */ - @Nullable - public Uri getVenueInfoUrl() { - return mVenueInfoUrl; - } - - /** - * Indicates whether the user portal URL can be used to extend sessions, when the user is logged - * in and the session has a time or byte limit. - */ - public boolean isSessionExtendable() { - return mIsSessionExtendable; - } - - /** - * Get the remaining bytes on the captive portal session, at the time {@link CaptivePortalData} - * was refreshed. This may be different from the limit currently enforced by the portal. - * @return The byte limit, or -1 if not set. - */ - public long getByteLimit() { - return mByteLimit; - } - - /** - * Get the time at the session will expire, as per {@link System#currentTimeMillis()}. - * @return The expiry time, or -1 if unset. - */ - public long getExpiryTimeMillis() { - return mExpiryTimeMillis; - } - - /** - * Get whether the network is captive (portal closed). - */ - public boolean isCaptive() { - return mCaptive; - } - - /** - * Get the venue friendly name - */ - @Nullable - public String getVenueFriendlyName() { - return mVenueFriendlyName; - } - - @NonNull - public static final Creator<CaptivePortalData> CREATOR = new Creator<CaptivePortalData>() { - @Override - public CaptivePortalData createFromParcel(Parcel source) { - return new CaptivePortalData(source); - } - - @Override - public CaptivePortalData[] newArray(int size) { - return new CaptivePortalData[size]; - } - }; - - @Override - public int hashCode() { - return Objects.hash(mRefreshTimeMillis, mUserPortalUrl, mVenueInfoUrl, - mIsSessionExtendable, mByteLimit, mExpiryTimeMillis, mCaptive, mVenueFriendlyName); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof CaptivePortalData)) return false; - final CaptivePortalData other = (CaptivePortalData) obj; - return mRefreshTimeMillis == other.mRefreshTimeMillis - && Objects.equals(mUserPortalUrl, other.mUserPortalUrl) - && Objects.equals(mVenueInfoUrl, other.mVenueInfoUrl) - && mIsSessionExtendable == other.mIsSessionExtendable - && mByteLimit == other.mByteLimit - && mExpiryTimeMillis == other.mExpiryTimeMillis - && mCaptive == other.mCaptive - && Objects.equals(mVenueFriendlyName, other.mVenueFriendlyName); - } - - @Override - public String toString() { - return "CaptivePortalData {" - + "refreshTime: " + mRefreshTimeMillis - + ", userPortalUrl: " + mUserPortalUrl - + ", venueInfoUrl: " + mVenueInfoUrl - + ", isSessionExtendable: " + mIsSessionExtendable - + ", byteLimit: " + mByteLimit - + ", expiryTime: " + mExpiryTimeMillis - + ", captive: " + mCaptive - + ", venueFriendlyName: " + mVenueFriendlyName - + "}"; - } -} diff --git a/core/java/android/net/ConnectionInfo.aidl b/core/java/android/net/ConnectionInfo.aidl deleted file mode 100644 index 07faf8bbbed8..000000000000 --- a/core/java/android/net/ConnectionInfo.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* -** -** Copyright (C) 2018 The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -package android.net; - -parcelable ConnectionInfo; diff --git a/core/java/android/net/ConnectionInfo.java b/core/java/android/net/ConnectionInfo.java deleted file mode 100644 index 4514a8484d96..000000000000 --- a/core/java/android/net/ConnectionInfo.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.os.Parcel; -import android.os.Parcelable; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; - -/** - * Describe a network connection including local and remote address/port of a connection and the - * transport protocol. - * - * @hide - */ -public final class ConnectionInfo implements Parcelable { - public final int protocol; - public final InetSocketAddress local; - public final InetSocketAddress remote; - - @Override - public int describeContents() { - return 0; - } - - public ConnectionInfo(int protocol, InetSocketAddress local, InetSocketAddress remote) { - this.protocol = protocol; - this.local = local; - this.remote = remote; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(protocol); - out.writeByteArray(local.getAddress().getAddress()); - out.writeInt(local.getPort()); - out.writeByteArray(remote.getAddress().getAddress()); - out.writeInt(remote.getPort()); - } - - public static final @android.annotation.NonNull Creator<ConnectionInfo> CREATOR = new Creator<ConnectionInfo>() { - public ConnectionInfo createFromParcel(Parcel in) { - int protocol = in.readInt(); - InetAddress localAddress; - try { - localAddress = InetAddress.getByAddress(in.createByteArray()); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Invalid InetAddress"); - } - int localPort = in.readInt(); - InetAddress remoteAddress; - try { - remoteAddress = InetAddress.getByAddress(in.createByteArray()); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Invalid InetAddress"); - } - int remotePort = in.readInt(); - InetSocketAddress local = new InetSocketAddress(localAddress, localPort); - InetSocketAddress remote = new InetSocketAddress(remoteAddress, remotePort); - return new ConnectionInfo(protocol, local, remote); - } - - public ConnectionInfo[] newArray(int size) { - return new ConnectionInfo[size]; - } - }; -} diff --git a/core/java/android/net/ConnectivityDiagnosticsManager.aidl b/core/java/android/net/ConnectivityDiagnosticsManager.aidl deleted file mode 100644 index 82ba0ca113c5..000000000000 --- a/core/java/android/net/ConnectivityDiagnosticsManager.aidl +++ /dev/null @@ -1,21 +0,0 @@ -/** - * - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -parcelable ConnectivityDiagnosticsManager.ConnectivityReport; -parcelable ConnectivityDiagnosticsManager.DataStallReport;
\ No newline at end of file diff --git a/core/java/android/net/ConnectivityDiagnosticsManager.java b/core/java/android/net/ConnectivityDiagnosticsManager.java deleted file mode 100644 index 523449497345..000000000000 --- a/core/java/android/net/ConnectivityDiagnosticsManager.java +++ /dev/null @@ -1,777 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.StringDef; -import android.content.Context; -import android.os.Binder; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.PersistableBundle; -import android.os.RemoteException; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.Preconditions; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executor; - -/** - * Class that provides utilities for collecting network connectivity diagnostics information. - * Connectivity information is made available through triggerable diagnostics tools and by listening - * to System validations. Some diagnostics information may be permissions-restricted. - * - * <p>ConnectivityDiagnosticsManager is intended for use by applications offering network - * connectivity on a user device. These tools will provide several mechanisms for these applications - * to be alerted to network conditions as well as diagnose potential network issues themselves. - * - * <p>The primary responsibilities of this class are to: - * - * <ul> - * <li>Allow permissioned applications to register and unregister callbacks for network event - * notifications - * <li>Invoke callbacks for network event notifications, including: - * <ul> - * <li>Network validations - * <li>Data stalls - * <li>Connectivity reports from applications - * </ul> - * </ul> - */ -public class ConnectivityDiagnosticsManager { - /** @hide */ - @VisibleForTesting - public static final Map<ConnectivityDiagnosticsCallback, ConnectivityDiagnosticsBinder> - sCallbacks = new ConcurrentHashMap<>(); - - private final Context mContext; - private final IConnectivityManager mService; - - /** @hide */ - public ConnectivityDiagnosticsManager(Context context, IConnectivityManager service) { - mContext = Preconditions.checkNotNull(context, "missing context"); - mService = Preconditions.checkNotNull(service, "missing IConnectivityManager"); - } - - /** @hide */ - @VisibleForTesting - public static boolean persistableBundleEquals( - @Nullable PersistableBundle a, @Nullable PersistableBundle b) { - if (a == b) return true; - if (a == null || b == null) return false; - if (!Objects.equals(a.keySet(), b.keySet())) return false; - for (String key : a.keySet()) { - if (!Objects.equals(a.get(key), b.get(key))) return false; - } - return true; - } - - /** Class that includes connectivity information for a specific Network at a specific time. */ - public static final class ConnectivityReport implements Parcelable { - /** - * The overall status of the network is that it is invalid; it neither provides - * connectivity nor has been exempted from validation. - */ - public static final int NETWORK_VALIDATION_RESULT_INVALID = 0; - - /** - * The overall status of the network is that it is valid, this may be because it provides - * full Internet access (all probes succeeded), or because other properties of the network - * caused probes not to be run. - */ - // TODO: link to INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID - public static final int NETWORK_VALIDATION_RESULT_VALID = 1; - - /** - * The overall status of the network is that it provides partial connectivity; some - * probed services succeeded but others failed. - */ - // TODO: link to INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; - public static final int NETWORK_VALIDATION_RESULT_PARTIALLY_VALID = 2; - - /** - * Due to the properties of the network, validation was not performed. - */ - public static final int NETWORK_VALIDATION_RESULT_SKIPPED = 3; - - /** @hide */ - @IntDef( - prefix = {"NETWORK_VALIDATION_RESULT_"}, - value = { - NETWORK_VALIDATION_RESULT_INVALID, - NETWORK_VALIDATION_RESULT_VALID, - NETWORK_VALIDATION_RESULT_PARTIALLY_VALID, - NETWORK_VALIDATION_RESULT_SKIPPED - }) - @Retention(RetentionPolicy.SOURCE) - public @interface NetworkValidationResult {} - - /** - * The overall validation result for the Network being reported on. - * - * <p>The possible values for this key are: - * {@link #NETWORK_VALIDATION_RESULT_INVALID}, - * {@link #NETWORK_VALIDATION_RESULT_VALID}, - * {@link #NETWORK_VALIDATION_RESULT_PARTIALLY_VALID}, - * {@link #NETWORK_VALIDATION_RESULT_SKIPPED}. - * - * @see android.net.NetworkCapabilities#NET_CAPABILITY_VALIDATED - */ - @NetworkValidationResult - public static final String KEY_NETWORK_VALIDATION_RESULT = "networkValidationResult"; - - /** DNS probe. */ - // TODO: link to INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS - public static final int NETWORK_PROBE_DNS = 0x04; - - /** HTTP probe. */ - // TODO: link to INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP - public static final int NETWORK_PROBE_HTTP = 0x08; - - /** HTTPS probe. */ - // TODO: link to INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS; - public static final int NETWORK_PROBE_HTTPS = 0x10; - - /** Captive portal fallback probe. */ - // TODO: link to INetworkMonitor.NETWORK_VALIDATION_FALLBACK - public static final int NETWORK_PROBE_FALLBACK = 0x20; - - /** Private DNS (DNS over TLS) probd. */ - // TODO: link to INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS - public static final int NETWORK_PROBE_PRIVATE_DNS = 0x40; - - /** @hide */ - @IntDef( - prefix = {"NETWORK_PROBE_"}, - value = { - NETWORK_PROBE_DNS, - NETWORK_PROBE_HTTP, - NETWORK_PROBE_HTTPS, - NETWORK_PROBE_FALLBACK, - NETWORK_PROBE_PRIVATE_DNS - }) - @Retention(RetentionPolicy.SOURCE) - public @interface NetworkProbe {} - - /** - * A bitmask of network validation probes that succeeded. - * - * <p>The possible bits values reported by this key are: - * {@link #NETWORK_PROBE_DNS}, - * {@link #NETWORK_PROBE_HTTP}, - * {@link #NETWORK_PROBE_HTTPS}, - * {@link #NETWORK_PROBE_FALLBACK}, - * {@link #NETWORK_PROBE_PRIVATE_DNS}. - */ - @NetworkProbe - public static final String KEY_NETWORK_PROBES_SUCCEEDED_BITMASK = - "networkProbesSucceeded"; - - /** - * A bitmask of network validation probes that were attempted. - * - * <p>These probes may have failed or may be incomplete at the time of this report. - * - * <p>The possible bits values reported by this key are: - * {@link #NETWORK_PROBE_DNS}, - * {@link #NETWORK_PROBE_HTTP}, - * {@link #NETWORK_PROBE_HTTPS}, - * {@link #NETWORK_PROBE_FALLBACK}, - * {@link #NETWORK_PROBE_PRIVATE_DNS}. - */ - @NetworkProbe - public static final String KEY_NETWORK_PROBES_ATTEMPTED_BITMASK = - "networkProbesAttempted"; - - /** @hide */ - @StringDef(prefix = {"KEY_"}, value = { - KEY_NETWORK_VALIDATION_RESULT, KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, - KEY_NETWORK_PROBES_ATTEMPTED_BITMASK}) - @Retention(RetentionPolicy.SOURCE) - public @interface ConnectivityReportBundleKeys {} - - /** The Network for which this ConnectivityReport applied */ - @NonNull private final Network mNetwork; - - /** - * The timestamp for the report. The timestamp is taken from {@link - * System#currentTimeMillis}. - */ - private final long mReportTimestamp; - - /** LinkProperties available on the Network at the reported timestamp */ - @NonNull private final LinkProperties mLinkProperties; - - /** NetworkCapabilities available on the Network at the reported timestamp */ - @NonNull private final NetworkCapabilities mNetworkCapabilities; - - /** PersistableBundle that may contain additional info about the report */ - @NonNull private final PersistableBundle mAdditionalInfo; - - /** - * Constructor for ConnectivityReport. - * - * <p>Apps should obtain instances through {@link - * ConnectivityDiagnosticsCallback#onConnectivityReportAvailable} instead of instantiating - * their own instances (unless for testing purposes). - * - * @param network The Network for which this ConnectivityReport applies - * @param reportTimestamp The timestamp for the report - * @param linkProperties The LinkProperties available on network at reportTimestamp - * @param networkCapabilities The NetworkCapabilities available on network at - * reportTimestamp - * @param additionalInfo A PersistableBundle that may contain additional info about the - * report - */ - public ConnectivityReport( - @NonNull Network network, - long reportTimestamp, - @NonNull LinkProperties linkProperties, - @NonNull NetworkCapabilities networkCapabilities, - @NonNull PersistableBundle additionalInfo) { - mNetwork = network; - mReportTimestamp = reportTimestamp; - mLinkProperties = new LinkProperties(linkProperties); - mNetworkCapabilities = new NetworkCapabilities(networkCapabilities); - mAdditionalInfo = additionalInfo; - } - - /** - * Returns the Network for this ConnectivityReport. - * - * @return The Network for which this ConnectivityReport applied - */ - @NonNull - public Network getNetwork() { - return mNetwork; - } - - /** - * Returns the epoch timestamp (milliseconds) for when this report was taken. - * - * @return The timestamp for the report. Taken from {@link System#currentTimeMillis}. - */ - public long getReportTimestamp() { - return mReportTimestamp; - } - - /** - * Returns the LinkProperties available when this report was taken. - * - * @return LinkProperties available on the Network at the reported timestamp - */ - @NonNull - public LinkProperties getLinkProperties() { - return new LinkProperties(mLinkProperties); - } - - /** - * Returns the NetworkCapabilities when this report was taken. - * - * @return NetworkCapabilities available on the Network at the reported timestamp - */ - @NonNull - public NetworkCapabilities getNetworkCapabilities() { - return new NetworkCapabilities(mNetworkCapabilities); - } - - /** - * Returns a PersistableBundle with additional info for this report. - * - * @return PersistableBundle that may contain additional info about the report - */ - @NonNull - public PersistableBundle getAdditionalInfo() { - return new PersistableBundle(mAdditionalInfo); - } - - @Override - public boolean equals(@Nullable Object o) { - if (this == o) return true; - if (!(o instanceof ConnectivityReport)) return false; - final ConnectivityReport that = (ConnectivityReport) o; - - // PersistableBundle is optimized to avoid unparcelling data unless fields are - // referenced. Because of this, use {@link ConnectivityDiagnosticsManager#equals} over - // {@link PersistableBundle#kindofEquals}. - return mReportTimestamp == that.mReportTimestamp - && mNetwork.equals(that.mNetwork) - && mLinkProperties.equals(that.mLinkProperties) - && mNetworkCapabilities.equals(that.mNetworkCapabilities) - && persistableBundleEquals(mAdditionalInfo, that.mAdditionalInfo); - } - - @Override - public int hashCode() { - return Objects.hash( - mNetwork, - mReportTimestamp, - mLinkProperties, - mNetworkCapabilities, - mAdditionalInfo); - } - - /** {@inheritDoc} */ - @Override - public int describeContents() { - return 0; - } - - /** {@inheritDoc} */ - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeParcelable(mNetwork, flags); - dest.writeLong(mReportTimestamp); - dest.writeParcelable(mLinkProperties, flags); - dest.writeParcelable(mNetworkCapabilities, flags); - dest.writeParcelable(mAdditionalInfo, flags); - } - - /** Implement the Parcelable interface */ - public static final @NonNull Creator<ConnectivityReport> CREATOR = - new Creator<ConnectivityReport>() { - public ConnectivityReport createFromParcel(Parcel in) { - return new ConnectivityReport( - in.readParcelable(null), - in.readLong(), - in.readParcelable(null), - in.readParcelable(null), - in.readParcelable(null)); - } - - public ConnectivityReport[] newArray(int size) { - return new ConnectivityReport[size]; - } - }; - } - - /** Class that includes information for a suspected data stall on a specific Network */ - public static final class DataStallReport implements Parcelable { - /** - * Indicates that the Data Stall was detected using DNS events. - */ - public static final int DETECTION_METHOD_DNS_EVENTS = 1; - - /** - * Indicates that the Data Stall was detected using TCP metrics. - */ - public static final int DETECTION_METHOD_TCP_METRICS = 2; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef( - prefix = {"DETECTION_METHOD_"}, - value = {DETECTION_METHOD_DNS_EVENTS, DETECTION_METHOD_TCP_METRICS}) - public @interface DetectionMethod {} - - /** - * This key represents the period in milliseconds over which other included TCP metrics - * were measured. - * - * <p>This key will be included if the data stall detection method is - * {@link #DETECTION_METHOD_TCP_METRICS}. - * - * <p>This value is an int. - */ - public static final String KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS = - "tcpMetricsCollectionPeriodMillis"; - - /** - * This key represents the fail rate of TCP packets when the suspected data stall was - * detected. - * - * <p>This key will be included if the data stall detection method is - * {@link #DETECTION_METHOD_TCP_METRICS}. - * - * <p>This value is an int percentage between 0 and 100. - */ - public static final String KEY_TCP_PACKET_FAIL_RATE = "tcpPacketFailRate"; - - /** - * This key represents the consecutive number of DNS timeouts that have occurred. - * - * <p>The consecutive count will be reset any time a DNS response is received. - * - * <p>This key will be included if the data stall detection method is - * {@link #DETECTION_METHOD_DNS_EVENTS}. - * - * <p>This value is an int. - */ - public static final String KEY_DNS_CONSECUTIVE_TIMEOUTS = "dnsConsecutiveTimeouts"; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @StringDef(prefix = {"KEY_"}, value = { - KEY_TCP_PACKET_FAIL_RATE, - KEY_DNS_CONSECUTIVE_TIMEOUTS - }) - public @interface DataStallReportBundleKeys {} - - /** The Network for which this DataStallReport applied */ - @NonNull private final Network mNetwork; - - /** - * The timestamp for the report. The timestamp is taken from {@link - * System#currentTimeMillis}. - */ - private long mReportTimestamp; - - /** A bitmask of the detection methods used to identify the suspected data stall */ - @DetectionMethod private final int mDetectionMethod; - - /** LinkProperties available on the Network at the reported timestamp */ - @NonNull private final LinkProperties mLinkProperties; - - /** NetworkCapabilities available on the Network at the reported timestamp */ - @NonNull private final NetworkCapabilities mNetworkCapabilities; - - /** PersistableBundle that may contain additional information on the suspected data stall */ - @NonNull private final PersistableBundle mStallDetails; - - /** - * Constructor for DataStallReport. - * - * <p>Apps should obtain instances through {@link - * ConnectivityDiagnosticsCallback#onDataStallSuspected} instead of instantiating their own - * instances (unless for testing purposes). - * - * @param network The Network for which this DataStallReport applies - * @param reportTimestamp The timestamp for the report - * @param detectionMethod The detection method used to identify this data stall - * @param linkProperties The LinkProperties available on network at reportTimestamp - * @param networkCapabilities The NetworkCapabilities available on network at - * reportTimestamp - * @param stallDetails A PersistableBundle that may contain additional info about the report - */ - public DataStallReport( - @NonNull Network network, - long reportTimestamp, - @DetectionMethod int detectionMethod, - @NonNull LinkProperties linkProperties, - @NonNull NetworkCapabilities networkCapabilities, - @NonNull PersistableBundle stallDetails) { - mNetwork = network; - mReportTimestamp = reportTimestamp; - mDetectionMethod = detectionMethod; - mLinkProperties = new LinkProperties(linkProperties); - mNetworkCapabilities = new NetworkCapabilities(networkCapabilities); - mStallDetails = stallDetails; - } - - /** - * Returns the Network for this DataStallReport. - * - * @return The Network for which this DataStallReport applied - */ - @NonNull - public Network getNetwork() { - return mNetwork; - } - - /** - * Returns the epoch timestamp (milliseconds) for when this report was taken. - * - * @return The timestamp for the report. Taken from {@link System#currentTimeMillis}. - */ - public long getReportTimestamp() { - return mReportTimestamp; - } - - /** - * Returns the bitmask of detection methods used to identify this suspected data stall. - * - * @return The bitmask of detection methods used to identify the suspected data stall - */ - public int getDetectionMethod() { - return mDetectionMethod; - } - - /** - * Returns the LinkProperties available when this report was taken. - * - * @return LinkProperties available on the Network at the reported timestamp - */ - @NonNull - public LinkProperties getLinkProperties() { - return new LinkProperties(mLinkProperties); - } - - /** - * Returns the NetworkCapabilities when this report was taken. - * - * @return NetworkCapabilities available on the Network at the reported timestamp - */ - @NonNull - public NetworkCapabilities getNetworkCapabilities() { - return new NetworkCapabilities(mNetworkCapabilities); - } - - /** - * Returns a PersistableBundle with additional info for this report. - * - * <p>Gets a bundle with details about the suspected data stall including information - * specific to the monitoring method that detected the data stall. - * - * @return PersistableBundle that may contain additional information on the suspected data - * stall - */ - @NonNull - public PersistableBundle getStallDetails() { - return new PersistableBundle(mStallDetails); - } - - @Override - public boolean equals(@Nullable Object o) { - if (this == o) return true; - if (!(o instanceof DataStallReport)) return false; - final DataStallReport that = (DataStallReport) o; - - // PersistableBundle is optimized to avoid unparcelling data unless fields are - // referenced. Because of this, use {@link ConnectivityDiagnosticsManager#equals} over - // {@link PersistableBundle#kindofEquals}. - return mReportTimestamp == that.mReportTimestamp - && mDetectionMethod == that.mDetectionMethod - && mNetwork.equals(that.mNetwork) - && mLinkProperties.equals(that.mLinkProperties) - && mNetworkCapabilities.equals(that.mNetworkCapabilities) - && persistableBundleEquals(mStallDetails, that.mStallDetails); - } - - @Override - public int hashCode() { - return Objects.hash( - mNetwork, - mReportTimestamp, - mDetectionMethod, - mLinkProperties, - mNetworkCapabilities, - mStallDetails); - } - - /** {@inheritDoc} */ - @Override - public int describeContents() { - return 0; - } - - /** {@inheritDoc} */ - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeParcelable(mNetwork, flags); - dest.writeLong(mReportTimestamp); - dest.writeInt(mDetectionMethod); - dest.writeParcelable(mLinkProperties, flags); - dest.writeParcelable(mNetworkCapabilities, flags); - dest.writeParcelable(mStallDetails, flags); - } - - /** Implement the Parcelable interface */ - public static final @NonNull Creator<DataStallReport> CREATOR = - new Creator<DataStallReport>() { - public DataStallReport createFromParcel(Parcel in) { - return new DataStallReport( - in.readParcelable(null), - in.readLong(), - in.readInt(), - in.readParcelable(null), - in.readParcelable(null), - in.readParcelable(null)); - } - - public DataStallReport[] newArray(int size) { - return new DataStallReport[size]; - } - }; - } - - /** @hide */ - @VisibleForTesting - public static class ConnectivityDiagnosticsBinder - extends IConnectivityDiagnosticsCallback.Stub { - @NonNull private final ConnectivityDiagnosticsCallback mCb; - @NonNull private final Executor mExecutor; - - /** @hide */ - @VisibleForTesting - public ConnectivityDiagnosticsBinder( - @NonNull ConnectivityDiagnosticsCallback cb, @NonNull Executor executor) { - this.mCb = cb; - this.mExecutor = executor; - } - - /** @hide */ - @VisibleForTesting - public void onConnectivityReportAvailable(@NonNull ConnectivityReport report) { - final long token = Binder.clearCallingIdentity(); - try { - mExecutor.execute(() -> { - mCb.onConnectivityReportAvailable(report); - }); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - /** @hide */ - @VisibleForTesting - public void onDataStallSuspected(@NonNull DataStallReport report) { - final long token = Binder.clearCallingIdentity(); - try { - mExecutor.execute(() -> { - mCb.onDataStallSuspected(report); - }); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - /** @hide */ - @VisibleForTesting - public void onNetworkConnectivityReported( - @NonNull Network network, boolean hasConnectivity) { - final long token = Binder.clearCallingIdentity(); - try { - mExecutor.execute(() -> { - mCb.onNetworkConnectivityReported(network, hasConnectivity); - }); - } finally { - Binder.restoreCallingIdentity(token); - } - } - } - - /** - * Abstract base class for Connectivity Diagnostics callbacks. Used for notifications about - * network connectivity events. Must be extended by applications wanting notifications. - */ - public abstract static class ConnectivityDiagnosticsCallback { - /** - * Called when the platform completes a data connectivity check. This will also be invoked - * immediately upon registration for each network matching the request with the latest - * report, if a report has already been generated for that network. - * - * <p>The Network specified in the ConnectivityReport may not be active any more when this - * method is invoked. - * - * @param report The ConnectivityReport containing information about a connectivity check - */ - public void onConnectivityReportAvailable(@NonNull ConnectivityReport report) {} - - /** - * Called when the platform suspects a data stall on some Network. - * - * <p>The Network specified in the DataStallReport may not be active any more when this - * method is invoked. - * - * @param report The DataStallReport containing information about the suspected data stall - */ - public void onDataStallSuspected(@NonNull DataStallReport report) {} - - /** - * Called when any app reports connectivity to the System. - * - * @param network The Network for which connectivity has been reported - * @param hasConnectivity The connectivity reported to the System - */ - public void onNetworkConnectivityReported( - @NonNull Network network, boolean hasConnectivity) {} - } - - /** - * Registers a ConnectivityDiagnosticsCallback with the System. - * - * <p>Only apps that offer network connectivity to the user should be registering callbacks. - * These are the only apps whose callbacks will be invoked by the system. Apps considered to - * meet these conditions include: - * - * <ul> - * <li>Carrier apps with active subscriptions - * <li>Active VPNs - * <li>WiFi Suggesters - * </ul> - * - * <p>Callbacks registered by apps not meeting the above criteria will not be invoked. - * - * <p>If a registering app loses its relevant permissions, any callbacks it registered will - * silently stop receiving callbacks. - * - * <p>Each register() call <b>MUST</b> use a ConnectivityDiagnosticsCallback instance that is - * not currently registered. If a ConnectivityDiagnosticsCallback instance is registered with - * multiple NetworkRequests, an IllegalArgumentException will be thrown. - * - * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the - * number of outstanding requests to 100 per app (identified by their UID), shared with - * callbacks in {@link ConnectivityManager}. Registering a callback with this method will count - * toward this limit. If this limit is exceeded, an exception will be thrown. To avoid hitting - * this issue and to conserve resources, make sure to unregister the callbacks with - * {@link #unregisterConnectivityDiagnosticsCallback}. - * - * @param request The NetworkRequest that will be used to match with Networks for which - * callbacks will be fired - * @param e The Executor to be used for running the callback method invocations - * @param callback The ConnectivityDiagnosticsCallback that the caller wants registered with the - * System - * @throws IllegalArgumentException if the same callback instance is registered with multiple - * NetworkRequests - * @throws RuntimeException if the app already has too many callbacks registered. - */ - public void registerConnectivityDiagnosticsCallback( - @NonNull NetworkRequest request, - @NonNull Executor e, - @NonNull ConnectivityDiagnosticsCallback callback) { - final ConnectivityDiagnosticsBinder binder = new ConnectivityDiagnosticsBinder(callback, e); - if (sCallbacks.putIfAbsent(callback, binder) != null) { - throw new IllegalArgumentException("Callback is currently registered"); - } - - try { - mService.registerConnectivityDiagnosticsCallback( - binder, request, mContext.getOpPackageName()); - } catch (RemoteException exception) { - exception.rethrowFromSystemServer(); - } - } - - /** - * Unregisters a ConnectivityDiagnosticsCallback with the System. - * - * <p>If the given callback is not currently registered with the System, this operation will be - * a no-op. - * - * @param callback The ConnectivityDiagnosticsCallback to be unregistered from the System. - */ - public void unregisterConnectivityDiagnosticsCallback( - @NonNull ConnectivityDiagnosticsCallback callback) { - // unconditionally removing from sCallbacks prevents race conditions here, since remove() is - // atomic. - final ConnectivityDiagnosticsBinder binder = sCallbacks.remove(callback); - if (binder == null) return; - - try { - mService.unregisterConnectivityDiagnosticsCallback(binder); - } catch (RemoteException exception) { - exception.rethrowFromSystemServer(); - } - } -} diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java deleted file mode 100644 index 7f07bba668a3..000000000000 --- a/core/java/android/net/ConnectivityManager.java +++ /dev/null @@ -1,5058 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net; - -import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; -import static android.net.IpSecManager.INVALID_RESOURCE_ID; -import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST; -import static android.net.NetworkRequest.Type.LISTEN; -import static android.net.NetworkRequest.Type.REQUEST; -import static android.net.NetworkRequest.Type.TRACK_DEFAULT; -import static android.net.QosCallback.QosCallbackRegistrationException; - -import android.annotation.CallbackExecutor; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; -import android.annotation.SdkConstant; -import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.SuppressLint; -import android.annotation.SystemApi; -import android.annotation.SystemService; -import android.app.PendingIntent; -import android.compat.annotation.UnsupportedAppUsage; -import android.content.Context; -import android.content.Intent; -import android.net.IpSecManager.UdpEncapsulationSocket; -import android.net.SocketKeepalive.Callback; -import android.net.TetheringManager.StartTetheringCallback; -import android.net.TetheringManager.TetheringEventCallback; -import android.net.TetheringManager.TetheringRequest; -import android.os.Binder; -import android.os.Build; -import android.os.Build.VERSION_CODES; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.INetworkActivityListener; -import android.os.INetworkManagementService; -import android.os.Looper; -import android.os.Message; -import android.os.Messenger; -import android.os.ParcelFileDescriptor; -import android.os.PersistableBundle; -import android.os.Process; -import android.os.RemoteException; -import android.os.ResultReceiver; -import android.os.ServiceManager; -import android.os.ServiceSpecificException; -import android.provider.Settings; -import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; -import android.util.ArrayMap; -import android.util.Log; -import android.util.Range; -import android.util.SparseIntArray; - -import com.android.connectivity.aidl.INetworkAgent; -import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.Preconditions; -import com.android.internal.util.Protocol; - -import libcore.net.event.NetworkEventDispatcher; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.RejectedExecutionException; - -/** - * Class that answers queries about the state of network connectivity. It also - * notifies applications when network connectivity changes. - * <p> - * The primary responsibilities of this class are to: - * <ol> - * <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li> - * <li>Send broadcast intents when network connectivity changes</li> - * <li>Attempt to "fail over" to another network when connectivity to a network - * is lost</li> - * <li>Provide an API that allows applications to query the coarse-grained or fine-grained - * state of the available networks</li> - * <li>Provide an API that allows applications to request and select networks for their data - * traffic</li> - * </ol> - */ -@SystemService(Context.CONNECTIVITY_SERVICE) -public class ConnectivityManager { - private static final String TAG = "ConnectivityManager"; - private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - - /** - * A change in network connectivity has occurred. A default connection has either - * been established or lost. The NetworkInfo for the affected network is - * sent as an extra; it should be consulted to see what kind of - * connectivity event occurred. - * <p/> - * Apps targeting Android 7.0 (API level 24) and higher do not receive this - * broadcast if they declare the broadcast receiver in their manifest. Apps - * will still receive broadcasts if they register their - * {@link android.content.BroadcastReceiver} with - * {@link android.content.Context#registerReceiver Context.registerReceiver()} - * and that context is still valid. - * <p/> - * If this is a connection that was the result of failing over from a - * disconnected network, then the FAILOVER_CONNECTION boolean extra is - * set to true. - * <p/> - * For a loss of connectivity, if the connectivity manager is attempting - * to connect (or has already connected) to another network, the - * NetworkInfo for the new network is also passed as an extra. This lets - * any receivers of the broadcast know that they should not necessarily - * tell the user that no data traffic will be possible. Instead, the - * receiver should expect another broadcast soon, indicating either that - * the failover attempt succeeded (and so there is still overall data - * connectivity), or that the failover attempt failed, meaning that all - * connectivity has been lost. - * <p/> - * For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY - * is set to {@code true} if there are no connected networks at all. - * - * @deprecated apps should use the more versatile {@link #requestNetwork}, - * {@link #registerNetworkCallback} or {@link #registerDefaultNetworkCallback} - * functions instead for faster and more detailed updates about the network - * changes they care about. - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @Deprecated - public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; - - /** - * The device has connected to a network that has presented a captive - * portal, which is blocking Internet connectivity. The user was presented - * with a notification that network sign in is required, - * and the user invoked the notification's action indicating they - * desire to sign in to the network. Apps handling this activity should - * facilitate signing in to the network. This action includes a - * {@link Network} typed extra called {@link #EXTRA_NETWORK} that represents - * the network presenting the captive portal; all communication with the - * captive portal must be done using this {@code Network} object. - * <p/> - * This activity includes a {@link CaptivePortal} extra named - * {@link #EXTRA_CAPTIVE_PORTAL} that can be used to indicate different - * outcomes of the captive portal sign in to the system: - * <ul> - * <li> When the app handling this action believes the user has signed in to - * the network and the captive portal has been dismissed, the app should - * call {@link CaptivePortal#reportCaptivePortalDismissed} so the system can - * reevaluate the network. If reevaluation finds the network no longer - * subject to a captive portal, the network may become the default active - * data network.</li> - * <li> When the app handling this action believes the user explicitly wants - * to ignore the captive portal and the network, the app should call - * {@link CaptivePortal#ignoreNetwork}. </li> - * </ul> - */ - @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL"; - - /** - * The lookup key for a {@link NetworkInfo} object. Retrieve with - * {@link android.content.Intent#getParcelableExtra(String)}. - * - * @deprecated The {@link NetworkInfo} object is deprecated, as many of its properties - * can't accurately represent modern network characteristics. - * Please obtain information about networks from the {@link NetworkCapabilities} - * or {@link LinkProperties} objects instead. - */ - @Deprecated - public static final String EXTRA_NETWORK_INFO = "networkInfo"; - - /** - * Network type which triggered a {@link #CONNECTIVITY_ACTION} broadcast. - * - * @see android.content.Intent#getIntExtra(String, int) - * @deprecated The network type is not rich enough to represent the characteristics - * of modern networks. Please use {@link NetworkCapabilities} instead, - * in particular the transports. - */ - @Deprecated - public static final String EXTRA_NETWORK_TYPE = "networkType"; - - /** - * The lookup key for a boolean that indicates whether a connect event - * is for a network to which the connectivity manager was failing over - * following a disconnect on another network. - * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}. - * - * @deprecated See {@link NetworkInfo}. - */ - @Deprecated - public static final String EXTRA_IS_FAILOVER = "isFailover"; - /** - * The lookup key for a {@link NetworkInfo} object. This is supplied when - * there is another network that it may be possible to connect to. Retrieve with - * {@link android.content.Intent#getParcelableExtra(String)}. - * - * @deprecated See {@link NetworkInfo}. - */ - @Deprecated - public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork"; - /** - * The lookup key for a boolean that indicates whether there is a - * complete lack of connectivity, i.e., no network is available. - * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}. - */ - public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity"; - /** - * The lookup key for a string that indicates why an attempt to connect - * to a network failed. The string has no particular structure. It is - * intended to be used in notifications presented to users. Retrieve - * it with {@link android.content.Intent#getStringExtra(String)}. - */ - public static final String EXTRA_REASON = "reason"; - /** - * The lookup key for a string that provides optionally supplied - * extra information about the network state. The information - * may be passed up from the lower networking layers, and its - * meaning may be specific to a particular network type. Retrieve - * it with {@link android.content.Intent#getStringExtra(String)}. - * - * @deprecated See {@link NetworkInfo#getExtraInfo()}. - */ - @Deprecated - public static final String EXTRA_EXTRA_INFO = "extraInfo"; - /** - * The lookup key for an int that provides information about - * our connection to the internet at large. 0 indicates no connection, - * 100 indicates a great connection. Retrieve it with - * {@link android.content.Intent#getIntExtra(String, int)}. - * {@hide} - */ - public static final String EXTRA_INET_CONDITION = "inetCondition"; - /** - * The lookup key for a {@link CaptivePortal} object included with the - * {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN} intent. The {@code CaptivePortal} - * object can be used to either indicate to the system that the captive - * portal has been dismissed or that the user does not want to pursue - * signing in to captive portal. Retrieve it with - * {@link android.content.Intent#getParcelableExtra(String)}. - */ - public static final String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL"; - - /** - * Key for passing a URL to the captive portal login activity. - */ - public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL"; - - /** - * Key for passing a {@link android.net.captiveportal.CaptivePortalProbeSpec} to the captive - * portal login activity. - * {@hide} - */ - @SystemApi - public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = - "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC"; - - /** - * Key for passing a user agent string to the captive portal login activity. - * {@hide} - */ - @SystemApi - public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = - "android.net.extra.CAPTIVE_PORTAL_USER_AGENT"; - - /** - * Broadcast action to indicate the change of data activity status - * (idle or active) on a network in a recent period. - * The network becomes active when data transmission is started, or - * idle if there is no data transmission for a period of time. - * {@hide} - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_DATA_ACTIVITY_CHANGE = - "android.net.conn.DATA_ACTIVITY_CHANGE"; - /** - * The lookup key for an enum that indicates the network device type on which this data activity - * change happens. - * {@hide} - */ - public static final String EXTRA_DEVICE_TYPE = "deviceType"; - /** - * The lookup key for a boolean that indicates the device is active or not. {@code true} means - * it is actively sending or receiving data and {@code false} means it is idle. - * {@hide} - */ - public static final String EXTRA_IS_ACTIVE = "isActive"; - /** - * The lookup key for a long that contains the timestamp (nanos) of the radio state change. - * {@hide} - */ - public static final String EXTRA_REALTIME_NS = "tsNanos"; - - /** - * Broadcast Action: The setting for background data usage has changed - * values. Use {@link #getBackgroundDataSetting()} to get the current value. - * <p> - * If an application uses the network in the background, it should listen - * for this broadcast and stop using the background data if the value is - * {@code false}. - * <p> - * - * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability - * of background data depends on several combined factors, and - * this broadcast is no longer sent. Instead, when background - * data is unavailable, {@link #getActiveNetworkInfo()} will now - * appear disconnected. During first boot after a platform - * upgrade, this broadcast will be sent once if - * {@link #getBackgroundDataSetting()} was {@code false} before - * the upgrade. - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @Deprecated - public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED = - "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED"; - - /** - * Broadcast Action: The network connection may not be good - * uses {@code ConnectivityManager.EXTRA_INET_CONDITION} and - * {@code ConnectivityManager.EXTRA_NETWORK_INFO} to specify - * the network and it's condition. - * @hide - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @UnsupportedAppUsage - public static final String INET_CONDITION_ACTION = - "android.net.conn.INET_CONDITION_ACTION"; - - /** - * Broadcast Action: A tetherable connection has come or gone. - * Uses {@code ConnectivityManager.EXTRA_AVAILABLE_TETHER}, - * {@code ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY}, - * {@code ConnectivityManager.EXTRA_ACTIVE_TETHER}, and - * {@code ConnectivityManager.EXTRA_ERRORED_TETHER} to indicate - * the current state of tethering. Each include a list of - * interface names in that state (may be empty). - * @hide - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final String ACTION_TETHER_STATE_CHANGED = - TetheringManager.ACTION_TETHER_STATE_CHANGED; - - /** - * @hide - * gives a String[] listing all the interfaces configured for - * tethering and currently available for tethering. - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final String EXTRA_AVAILABLE_TETHER = TetheringManager.EXTRA_AVAILABLE_TETHER; - - /** - * @hide - * gives a String[] listing all the interfaces currently in local-only - * mode (ie, has DHCPv4+IPv6-ULA support and no packet forwarding) - */ - public static final String EXTRA_ACTIVE_LOCAL_ONLY = TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; - - /** - * @hide - * gives a String[] listing all the interfaces currently tethered - * (ie, has DHCPv4 support and packets potentially forwarded/NATed) - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final String EXTRA_ACTIVE_TETHER = TetheringManager.EXTRA_ACTIVE_TETHER; - - /** - * @hide - * gives a String[] listing all the interfaces we tried to tether and - * failed. Use {@link #getLastTetherError} to find the error code - * for any interfaces listed here. - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final String EXTRA_ERRORED_TETHER = TetheringManager.EXTRA_ERRORED_TETHER; - - /** - * Broadcast Action: The captive portal tracker has finished its test. - * Sent only while running Setup Wizard, in lieu of showing a user - * notification. - * @hide - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED = - "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED"; - /** - * The lookup key for a boolean that indicates whether a captive portal was detected. - * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}. - * @hide - */ - public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal"; - - /** - * Action used to display a dialog that asks the user whether to connect to a network that is - * not validated. This intent is used to start the dialog in settings via startActivity. - * - * @hide - */ - public static final String ACTION_PROMPT_UNVALIDATED = "android.net.conn.PROMPT_UNVALIDATED"; - - /** - * Action used to display a dialog that asks the user whether to avoid a network that is no - * longer validated. This intent is used to start the dialog in settings via startActivity. - * - * @hide - */ - public static final String ACTION_PROMPT_LOST_VALIDATION = - "android.net.conn.PROMPT_LOST_VALIDATION"; - - /** - * Action used to display a dialog that asks the user whether to stay connected to a network - * that has not validated. This intent is used to start the dialog in settings via - * startActivity. - * - * @hide - */ - public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY = - "android.net.conn.PROMPT_PARTIAL_CONNECTIVITY"; - - /** - * Invalid tethering type. - * @see #startTethering(int, boolean, OnStartTetheringCallback) - * @hide - */ - public static final int TETHERING_INVALID = TetheringManager.TETHERING_INVALID; - - /** - * Wifi tethering type. - * @see #startTethering(int, boolean, OnStartTetheringCallback) - * @hide - */ - @SystemApi - public static final int TETHERING_WIFI = TetheringManager.TETHERING_WIFI; - - /** - * USB tethering type. - * @see #startTethering(int, boolean, OnStartTetheringCallback) - * @hide - */ - @SystemApi - public static final int TETHERING_USB = TetheringManager.TETHERING_USB; - - /** - * Bluetooth tethering type. - * @see #startTethering(int, boolean, OnStartTetheringCallback) - * @hide - */ - @SystemApi - public static final int TETHERING_BLUETOOTH = TetheringManager.TETHERING_BLUETOOTH; - - /** - * Wifi P2p tethering type. - * Wifi P2p tethering is set through events automatically, and don't - * need to start from #startTethering(int, boolean, OnStartTetheringCallback). - * @hide - */ - public static final int TETHERING_WIFI_P2P = TetheringManager.TETHERING_WIFI_P2P; - - /** - * Extra used for communicating with the TetherService. Includes the type of tethering to - * enable if any. - * @hide - */ - public static final String EXTRA_ADD_TETHER_TYPE = TetheringConstants.EXTRA_ADD_TETHER_TYPE; - - /** - * Extra used for communicating with the TetherService. Includes the type of tethering for - * which to cancel provisioning. - * @hide - */ - public static final String EXTRA_REM_TETHER_TYPE = TetheringConstants.EXTRA_REM_TETHER_TYPE; - - /** - * Extra used for communicating with the TetherService. True to schedule a recheck of tether - * provisioning. - * @hide - */ - public static final String EXTRA_SET_ALARM = TetheringConstants.EXTRA_SET_ALARM; - - /** - * Tells the TetherService to run a provision check now. - * @hide - */ - public static final String EXTRA_RUN_PROVISION = TetheringConstants.EXTRA_RUN_PROVISION; - - /** - * Extra used for communicating with the TetherService. Contains the {@link ResultReceiver} - * which will receive provisioning results. Can be left empty. - * @hide - */ - public static final String EXTRA_PROVISION_CALLBACK = - TetheringConstants.EXTRA_PROVISION_CALLBACK; - - /** - * The absence of a connection type. - * @hide - */ - @SystemApi - public static final int TYPE_NONE = -1; - - /** - * A Mobile data connection. Devices may support more than one. - * - * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or - * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an - * appropriate network. {@see NetworkCapabilities} for supported transports. - */ - @Deprecated - public static final int TYPE_MOBILE = 0; - - /** - * A WIFI data connection. Devices may support more than one. - * - * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or - * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an - * appropriate network. {@see NetworkCapabilities} for supported transports. - */ - @Deprecated - public static final int TYPE_WIFI = 1; - - /** - * An MMS-specific Mobile data connection. This network type may use the - * same network interface as {@link #TYPE_MOBILE} or it may use a different - * one. This is used by applications needing to talk to the carrier's - * Multimedia Messaging Service servers. - * - * @deprecated Applications should instead use {@link NetworkCapabilities#hasCapability} or - * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that - * provides the {@link NetworkCapabilities#NET_CAPABILITY_MMS} capability. - */ - @Deprecated - public static final int TYPE_MOBILE_MMS = 2; - - /** - * A SUPL-specific Mobile data connection. This network type may use the - * same network interface as {@link #TYPE_MOBILE} or it may use a different - * one. This is used by applications needing to talk to the carrier's - * Secure User Plane Location servers for help locating the device. - * - * @deprecated Applications should instead use {@link NetworkCapabilities#hasCapability} or - * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that - * provides the {@link NetworkCapabilities#NET_CAPABILITY_SUPL} capability. - */ - @Deprecated - public static final int TYPE_MOBILE_SUPL = 3; - - /** - * A DUN-specific Mobile data connection. This network type may use the - * same network interface as {@link #TYPE_MOBILE} or it may use a different - * one. This is sometimes by the system when setting up an upstream connection - * for tethering so that the carrier is aware of DUN traffic. - * - * @deprecated Applications should instead use {@link NetworkCapabilities#hasCapability} or - * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that - * provides the {@link NetworkCapabilities#NET_CAPABILITY_DUN} capability. - */ - @Deprecated - public static final int TYPE_MOBILE_DUN = 4; - - /** - * A High Priority Mobile data connection. This network type uses the - * same network interface as {@link #TYPE_MOBILE} but the routing setup - * is different. - * - * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or - * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an - * appropriate network. {@see NetworkCapabilities} for supported transports. - */ - @Deprecated - public static final int TYPE_MOBILE_HIPRI = 5; - - /** - * A WiMAX data connection. - * - * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or - * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an - * appropriate network. {@see NetworkCapabilities} for supported transports. - */ - @Deprecated - public static final int TYPE_WIMAX = 6; - - /** - * A Bluetooth data connection. - * - * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or - * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an - * appropriate network. {@see NetworkCapabilities} for supported transports. - */ - @Deprecated - public static final int TYPE_BLUETOOTH = 7; - - /** - * Fake data connection. This should not be used on shipping devices. - * @deprecated This is not used any more. - */ - @Deprecated - public static final int TYPE_DUMMY = 8; - - /** - * An Ethernet data connection. - * - * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or - * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an - * appropriate network. {@see NetworkCapabilities} for supported transports. - */ - @Deprecated - public static final int TYPE_ETHERNET = 9; - - /** - * Over the air Administration. - * @deprecated Use {@link NetworkCapabilities} instead. - * {@hide} - */ - @Deprecated - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) - public static final int TYPE_MOBILE_FOTA = 10; - - /** - * IP Multimedia Subsystem. - * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_IMS} instead. - * {@hide} - */ - @Deprecated - @UnsupportedAppUsage - public static final int TYPE_MOBILE_IMS = 11; - - /** - * Carrier Branded Services. - * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_CBS} instead. - * {@hide} - */ - @Deprecated - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) - public static final int TYPE_MOBILE_CBS = 12; - - /** - * A Wi-Fi p2p connection. Only requesting processes will have access to - * the peers connected. - * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_WIFI_P2P} instead. - * {@hide} - */ - @Deprecated - @SystemApi - public static final int TYPE_WIFI_P2P = 13; - - /** - * The network to use for initially attaching to the network - * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_IA} instead. - * {@hide} - */ - @Deprecated - @UnsupportedAppUsage - public static final int TYPE_MOBILE_IA = 14; - - /** - * Emergency PDN connection for emergency services. This - * may include IMS and MMS in emergency situations. - * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_EIMS} instead. - * {@hide} - */ - @Deprecated - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) - public static final int TYPE_MOBILE_EMERGENCY = 15; - - /** - * The network that uses proxy to achieve connectivity. - * @deprecated Use {@link NetworkCapabilities} instead. - * {@hide} - */ - @Deprecated - @SystemApi - public static final int TYPE_PROXY = 16; - - /** - * A virtual network using one or more native bearers. - * It may or may not be providing security services. - * @deprecated Applications should use {@link NetworkCapabilities#TRANSPORT_VPN} instead. - */ - @Deprecated - public static final int TYPE_VPN = 17; - - /** - * A network that is exclusively meant to be used for testing - * - * @deprecated Use {@link NetworkCapabilities} instead. - * @hide - */ - @Deprecated - public static final int TYPE_TEST = 18; // TODO: Remove this once NetworkTypes are unused. - - /** - * @deprecated Use {@link NetworkCapabilities} instead. - * @hide - */ - @Deprecated - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "TYPE_" }, value = { - TYPE_NONE, - TYPE_MOBILE, - TYPE_WIFI, - TYPE_MOBILE_MMS, - TYPE_MOBILE_SUPL, - TYPE_MOBILE_DUN, - TYPE_MOBILE_HIPRI, - TYPE_WIMAX, - TYPE_BLUETOOTH, - TYPE_DUMMY, - TYPE_ETHERNET, - TYPE_MOBILE_FOTA, - TYPE_MOBILE_IMS, - TYPE_MOBILE_CBS, - TYPE_WIFI_P2P, - TYPE_MOBILE_IA, - TYPE_MOBILE_EMERGENCY, - TYPE_PROXY, - TYPE_VPN, - TYPE_TEST - }) - public @interface LegacyNetworkType {} - - // Deprecated constants for return values of startUsingNetworkFeature. They used to live - // in com.android.internal.telephony.PhoneConstants until they were made inaccessible. - private static final int DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE = 0; - private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED = 1; - private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED = 3; - - /** {@hide} */ - public static final int MAX_RADIO_TYPE = TYPE_TEST; - - /** {@hide} */ - public static final int MAX_NETWORK_TYPE = TYPE_TEST; - - private static final int MIN_NETWORK_TYPE = TYPE_MOBILE; - - /** - * If you want to set the default network preference,you can directly - * change the networkAttributes array in framework's config.xml. - * - * @deprecated Since we support so many more networks now, the single - * network default network preference can't really express - * the hierarchy. Instead, the default is defined by the - * networkAttributes in config.xml. You can determine - * the current value by calling {@link #getNetworkPreference()} - * from an App. - */ - @Deprecated - public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI; - - /** - * @hide - */ - public static final int REQUEST_ID_UNSET = 0; - - /** - * Static unique request used as a tombstone for NetworkCallbacks that have been unregistered. - * This allows to distinguish when unregistering NetworkCallbacks those that were never - * registered from those that were already unregistered. - * @hide - */ - private static final NetworkRequest ALREADY_UNREGISTERED = - new NetworkRequest.Builder().clearCapabilities().build(); - - /** - * A NetID indicating no Network is selected. - * Keep in sync with bionic/libc/dns/include/resolv_netid.h - * @hide - */ - public static final int NETID_UNSET = 0; - - /** - * Private DNS Mode values. - * - * The "private_dns_mode" global setting stores a String value which is - * expected to be one of the following. - */ - - /** - * @hide - */ - public static final String PRIVATE_DNS_MODE_OFF = "off"; - /** - * @hide - */ - public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic"; - /** - * @hide - */ - public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname"; - /** - * The default Private DNS mode. - * - * This may change from release to release or may become dependent upon - * the capabilities of the underlying platform. - * - * @hide - */ - public static final String PRIVATE_DNS_DEFAULT_MODE_FALLBACK = PRIVATE_DNS_MODE_OPPORTUNISTIC; - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) - private final IConnectivityManager mService; - /** - * A kludge to facilitate static access where a Context pointer isn't available, like in the - * case of the static set/getProcessDefaultNetwork methods and from the Network class. - * TODO: Remove this after deprecating the static methods in favor of non-static methods or - * methods that take a Context argument. - */ - private static ConnectivityManager sInstance; - - private final Context mContext; - - private INetworkManagementService mNMService; - private INetworkPolicyManager mNPManager; - private final TetheringManager mTetheringManager; - - /** - * Tests if a given integer represents a valid network type. - * @param networkType the type to be tested - * @return a boolean. {@code true} if the type is valid, else {@code false} - * @deprecated All APIs accepting a network type are deprecated. There should be no need to - * validate a network type. - */ - @Deprecated - public static boolean isNetworkTypeValid(int networkType) { - return MIN_NETWORK_TYPE <= networkType && networkType <= MAX_NETWORK_TYPE; - } - - /** - * Returns a non-localized string representing a given network type. - * ONLY used for debugging output. - * @param type the type needing naming - * @return a String for the given type, or a string version of the type ("87") - * if no name is known. - * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead. - * {@hide} - */ - @Deprecated - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static String getNetworkTypeName(int type) { - switch (type) { - case TYPE_NONE: - return "NONE"; - case TYPE_MOBILE: - return "MOBILE"; - case TYPE_WIFI: - return "WIFI"; - case TYPE_MOBILE_MMS: - return "MOBILE_MMS"; - case TYPE_MOBILE_SUPL: - return "MOBILE_SUPL"; - case TYPE_MOBILE_DUN: - return "MOBILE_DUN"; - case TYPE_MOBILE_HIPRI: - return "MOBILE_HIPRI"; - case TYPE_WIMAX: - return "WIMAX"; - case TYPE_BLUETOOTH: - return "BLUETOOTH"; - case TYPE_DUMMY: - return "DUMMY"; - case TYPE_ETHERNET: - return "ETHERNET"; - case TYPE_MOBILE_FOTA: - return "MOBILE_FOTA"; - case TYPE_MOBILE_IMS: - return "MOBILE_IMS"; - case TYPE_MOBILE_CBS: - return "MOBILE_CBS"; - case TYPE_WIFI_P2P: - return "WIFI_P2P"; - case TYPE_MOBILE_IA: - return "MOBILE_IA"; - case TYPE_MOBILE_EMERGENCY: - return "MOBILE_EMERGENCY"; - case TYPE_PROXY: - return "PROXY"; - case TYPE_VPN: - return "VPN"; - default: - return Integer.toString(type); - } - } - - /** - * @hide - * TODO: Expose for SystemServer when becomes a module. - */ - public void systemReady() { - try { - mService.systemReady(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Checks if a given type uses the cellular data connection. - * This should be replaced in the future by a network property. - * @param networkType the type to check - * @return a boolean - {@code true} if uses cellular network, else {@code false} - * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead. - * {@hide} - */ - @Deprecated - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) - public static boolean isNetworkTypeMobile(int networkType) { - switch (networkType) { - case TYPE_MOBILE: - case TYPE_MOBILE_MMS: - case TYPE_MOBILE_SUPL: - case TYPE_MOBILE_DUN: - case TYPE_MOBILE_HIPRI: - case TYPE_MOBILE_FOTA: - case TYPE_MOBILE_IMS: - case TYPE_MOBILE_CBS: - case TYPE_MOBILE_IA: - case TYPE_MOBILE_EMERGENCY: - return true; - default: - return false; - } - } - - /** - * Checks if the given network type is backed by a Wi-Fi radio. - * - * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead. - * @hide - */ - @Deprecated - public static boolean isNetworkTypeWifi(int networkType) { - switch (networkType) { - case TYPE_WIFI: - case TYPE_WIFI_P2P: - return true; - default: - return false; - } - } - - /** - * Specifies the preferred network type. When the device has more - * than one type available the preferred network type will be used. - * - * @param preference the network type to prefer over all others. It is - * unspecified what happens to the old preferred network in the - * overall ordering. - * @deprecated Functionality has been removed as it no longer makes sense, - * with many more than two networks - we'd need an array to express - * preference. Instead we use dynamic network properties of - * the networks to describe their precedence. - */ - @Deprecated - public void setNetworkPreference(int preference) { - } - - /** - * Retrieves the current preferred network type. - * - * @return an integer representing the preferred network type - * - * @deprecated Functionality has been removed as it no longer makes sense, - * with many more than two networks - we'd need an array to express - * preference. Instead we use dynamic network properties of - * the networks to describe their precedence. - */ - @Deprecated - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public int getNetworkPreference() { - return TYPE_NONE; - } - - /** - * Returns details about the currently active default data network. When - * connected, this network is the default route for outgoing connections. - * You should always check {@link NetworkInfo#isConnected()} before initiating - * network traffic. This may return {@code null} when there is no default - * network. - * Note that if the default network is a VPN, this method will return the - * NetworkInfo for one of its underlying networks instead, or null if the - * VPN agent did not specify any. Apps interested in learning about VPNs - * should use {@link #getNetworkInfo(android.net.Network)} instead. - * - * @return a {@link NetworkInfo} object for the current default network - * or {@code null} if no default network is currently active - * @deprecated See {@link NetworkInfo}. - */ - @Deprecated - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @Nullable - public NetworkInfo getActiveNetworkInfo() { - try { - return mService.getActiveNetworkInfo(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns a {@link Network} object corresponding to the currently active - * default data network. In the event that the current active default data - * network disconnects, the returned {@code Network} object will no longer - * be usable. This will return {@code null} when there is no default - * network. - * - * @return a {@link Network} object for the current default network or - * {@code null} if no default network is currently active - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @Nullable - public Network getActiveNetwork() { - try { - return mService.getActiveNetwork(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns a {@link Network} object corresponding to the currently active - * default data network for a specific UID. In the event that the default data - * network disconnects, the returned {@code Network} object will no longer - * be usable. This will return {@code null} when there is no default - * network for the UID. - * - * @return a {@link Network} object for the current default network for the - * given UID or {@code null} if no default network is currently active - * - * @hide - */ - @RequiresPermission(android.Manifest.permission.NETWORK_STACK) - @Nullable - public Network getActiveNetworkForUid(int uid) { - return getActiveNetworkForUid(uid, false); - } - - /** {@hide} */ - public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) { - try { - return mService.getActiveNetworkForUid(uid, ignoreBlocked); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Checks if a VPN app supports always-on mode. - * - * In order to support the always-on feature, an app has to - * <ul> - * <li>target {@link VERSION_CODES#N API 24} or above, and - * <li>not opt out through the {@link VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON} - * meta-data field. - * </ul> - * - * @param userId The identifier of the user for whom the VPN app is installed. - * @param vpnPackage The canonical package name of the VPN app. - * @return {@code true} if and only if the VPN app exists and supports always-on mode. - * @hide - */ - public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) { - try { - return mService.isAlwaysOnVpnPackageSupported(userId, vpnPackage); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Configures an always-on VPN connection through a specific application. - * This connection is automatically granted and persisted after a reboot. - * - * <p>The designated package should declare a {@link VpnService} in its - * manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE}, - * otherwise the call will fail. - * - * @param userId The identifier of the user to set an always-on VPN for. - * @param vpnPackage The package name for an installed VPN app on the device, or {@code null} - * to remove an existing always-on VPN configuration. - * @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or - * {@code false} otherwise. - * @param lockdownAllowlist The list of packages that are allowed to access network directly - * when VPN is in lockdown mode but is not running. Non-existent packages are ignored so - * this method must be called when a package that should be allowed is installed or - * uninstalled. - * @return {@code true} if the package is set as always-on VPN controller; - * {@code false} otherwise. - * @hide - */ - @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN) - public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage, - boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) { - try { - return mService.setAlwaysOnVpnPackage( - userId, vpnPackage, lockdownEnabled, lockdownAllowlist); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns the package name of the currently set always-on VPN application. - * If there is no always-on VPN set, or the VPN is provided by the system instead - * of by an app, {@code null} will be returned. - * - * @return Package name of VPN controller responsible for always-on VPN, - * or {@code null} if none is set. - * @hide - */ - @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN) - public String getAlwaysOnVpnPackageForUser(int userId) { - try { - return mService.getAlwaysOnVpnPackage(userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * @return whether always-on VPN is in lockdown mode. - * - * @hide - **/ - @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN) - public boolean isVpnLockdownEnabled(int userId) { - try { - return mService.isVpnLockdownEnabled(userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - - } - - /** - * @return the list of packages that are allowed to access network when always-on VPN is in - * lockdown mode but not connected. Returns {@code null} when VPN lockdown is not active. - * - * @hide - **/ - @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN) - public List<String> getVpnLockdownWhitelist(int userId) { - try { - return mService.getVpnLockdownWhitelist(userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Adds or removes a requirement for given UID ranges to use the VPN. - * - * If set to {@code true}, informs the system that the UIDs in the specified ranges must not - * have any connectivity except if a VPN is connected and applies to the UIDs, or if the UIDs - * otherwise have permission to bypass the VPN (e.g., because they have the - * {@link android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS} permission, or when - * using a socket protected by a method such as {@link VpnService#protect(DatagramSocket)}. If - * set to {@code false}, a previously-added restriction is removed. - * <p> - * Each of the UID ranges specified by this method is added and removed as is, and no processing - * is performed on the ranges to de-duplicate, merge, split, or intersect them. In order to - * remove a previously-added range, the exact range must be removed as is. - * <p> - * The changes are applied asynchronously and may not have been applied by the time the method - * returns. Apps will be notified about any changes that apply to them via - * {@link NetworkCallback#onBlockedStatusChanged} callbacks called after the changes take - * effect. - * <p> - * This method should be called only by the VPN code. - * - * @param ranges the UID ranges to restrict - * @param requireVpn whether the specified UID ranges must use a VPN - * - * TODO: expose as @SystemApi. - * @hide - */ - @RequiresPermission(anyOf = { - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_STACK}) - public void setRequireVpnForUids(boolean requireVpn, - @NonNull Collection<Range<Integer>> ranges) { - Objects.requireNonNull(ranges); - // The Range class is not parcelable. Convert to UidRange, which is what is used internally. - // This method is not necessarily expected to be used outside the system server, so - // parceling may not be necessary, but it could be used out-of-process, e.g., by the network - // stack process, or by tests. - UidRange[] rangesArray = new UidRange[ranges.size()]; - int index = 0; - for (Range<Integer> range : ranges) { - rangesArray[index++] = new UidRange(range.getLower(), range.getUpper()); - } - try { - mService.setRequireVpnForUids(requireVpn, rangesArray); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns details about the currently active default data network - * for a given uid. This is for internal use only to avoid spying - * other apps. - * - * @return a {@link NetworkInfo} object for the current default network - * for the given uid or {@code null} if no default network is - * available for the specified uid. - * - * {@hide} - */ - @RequiresPermission(android.Manifest.permission.NETWORK_STACK) - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public NetworkInfo getActiveNetworkInfoForUid(int uid) { - return getActiveNetworkInfoForUid(uid, false); - } - - /** {@hide} */ - public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) { - try { - return mService.getActiveNetworkInfoForUid(uid, ignoreBlocked); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns connection status information about a particular - * network type. - * - * @param networkType integer specifying which networkType in - * which you're interested. - * @return a {@link NetworkInfo} object for the requested - * network type or {@code null} if the type is not - * supported by the device. If {@code networkType} is - * TYPE_VPN and a VPN is active for the calling app, - * then this method will try to return one of the - * underlying networks for the VPN or null if the - * VPN agent didn't specify any. - * - * @deprecated This method does not support multiple connected networks - * of the same type. Use {@link #getAllNetworks} and - * {@link #getNetworkInfo(android.net.Network)} instead. - */ - @Deprecated - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @Nullable - public NetworkInfo getNetworkInfo(int networkType) { - try { - return mService.getNetworkInfo(networkType); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns connection status information about a particular - * Network. - * - * @param network {@link Network} specifying which network - * in which you're interested. - * @return a {@link NetworkInfo} object for the requested - * network or {@code null} if the {@code Network} - * is not valid. - * @deprecated See {@link NetworkInfo}. - */ - @Deprecated - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @Nullable - public NetworkInfo getNetworkInfo(@Nullable Network network) { - return getNetworkInfoForUid(network, Process.myUid(), false); - } - - /** {@hide} */ - public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) { - try { - return mService.getNetworkInfoForUid(network, uid, ignoreBlocked); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns connection status information about all network - * types supported by the device. - * - * @return an array of {@link NetworkInfo} objects. Check each - * {@link NetworkInfo#getType} for which type each applies. - * - * @deprecated This method does not support multiple connected networks - * of the same type. Use {@link #getAllNetworks} and - * {@link #getNetworkInfo(android.net.Network)} instead. - */ - @Deprecated - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @NonNull - public NetworkInfo[] getAllNetworkInfo() { - try { - return mService.getAllNetworkInfo(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns the {@link Network} object currently serving a given type, or - * null if the given type is not connected. - * - * @hide - * @deprecated This method does not support multiple connected networks - * of the same type. Use {@link #getAllNetworks} and - * {@link #getNetworkInfo(android.net.Network)} instead. - */ - @Deprecated - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage - public Network getNetworkForType(int networkType) { - try { - return mService.getNetworkForType(networkType); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns an array of all {@link Network} currently tracked by the - * framework. - * - * @return an array of {@link Network} objects. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @NonNull - public Network[] getAllNetworks() { - try { - return mService.getAllNetworks(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns an array of {@link android.net.NetworkCapabilities} objects, representing - * the Networks that applications run by the given user will use by default. - * @hide - */ - @UnsupportedAppUsage - public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) { - try { - return mService.getDefaultNetworkCapabilitiesForUser( - userId, mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns the IP information for the current default network. - * - * @return a {@link LinkProperties} object describing the IP info - * for the current default network, or {@code null} if there - * is no current default network. - * - * {@hide} - * @deprecated please use {@link #getLinkProperties(Network)} on the return - * value of {@link #getActiveNetwork()} instead. In particular, - * this method will return non-null LinkProperties even if the - * app is blocked by policy from using this network. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 109783091) - public LinkProperties getActiveLinkProperties() { - try { - return mService.getActiveLinkProperties(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns the IP information for a given network type. - * - * @param networkType the network type of interest. - * @return a {@link LinkProperties} object describing the IP info - * for the given networkType, or {@code null} if there is - * no current default network. - * - * {@hide} - * @deprecated This method does not support multiple connected networks - * of the same type. Use {@link #getAllNetworks}, - * {@link #getNetworkInfo(android.net.Network)}, and - * {@link #getLinkProperties(android.net.Network)} instead. - */ - @Deprecated - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) - public LinkProperties getLinkProperties(int networkType) { - try { - return mService.getLinkPropertiesForType(networkType); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Get the {@link LinkProperties} for the given {@link Network}. This - * will return {@code null} if the network is unknown. - * - * @param network The {@link Network} object identifying the network in question. - * @return The {@link LinkProperties} for the network, or {@code null}. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @Nullable - public LinkProperties getLinkProperties(@Nullable Network network) { - try { - return mService.getLinkProperties(network); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Get the {@link android.net.NetworkCapabilities} for the given {@link Network}. This - * will return {@code null} if the network is unknown. - * - * @param network The {@link Network} object identifying the network in question. - * @return The {@link android.net.NetworkCapabilities} for the network, or {@code null}. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @Nullable - public NetworkCapabilities getNetworkCapabilities(@Nullable Network network) { - try { - return mService.getNetworkCapabilities(network, mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Gets a URL that can be used for resolving whether a captive portal is present. - * 1. This URL should respond with a 204 response to a GET request to indicate no captive - * portal is present. - * 2. This URL must be HTTP as redirect responses are used to find captive portal - * sign-in pages. Captive portals cannot respond to HTTPS requests with redirects. - * - * The system network validation may be using different strategies to detect captive portals, - * so this method does not necessarily return a URL used by the system. It only returns a URL - * that may be relevant for other components trying to detect captive portals. - * - * @hide - * @deprecated This API returns URL which is not guaranteed to be one of the URLs used by the - * system. - */ - @Deprecated - @SystemApi - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public String getCaptivePortalServerUrl() { - try { - return mService.getCaptivePortalServerUrl(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Tells the underlying networking system that the caller wants to - * begin using the named feature. The interpretation of {@code feature} - * is completely up to each networking implementation. - * - * <p>This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.</p> - * - * @param networkType specifies which network the request pertains to - * @param feature the name of the feature to be used - * @return an integer value representing the outcome of the request. - * The interpretation of this value is specific to each networking - * implementation+feature combination, except that the value {@code -1} - * always indicates failure. - * - * @deprecated Deprecated in favor of the cleaner - * {@link #requestNetwork(NetworkRequest, NetworkCallback)} API. - * In {@link VERSION_CODES#M}, and above, this method is unsupported and will - * throw {@code UnsupportedOperationException} if called. - * @removed - */ - @Deprecated - public int startUsingNetworkFeature(int networkType, String feature) { - checkLegacyRoutingApiAccess(); - NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature); - if (netCap == null) { - Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " + - feature); - return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED; - } - - NetworkRequest request = null; - synchronized (sLegacyRequests) { - LegacyRequest l = sLegacyRequests.get(netCap); - if (l != null) { - Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest); - renewRequestLocked(l); - if (l.currentNetwork != null) { - return DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE; - } else { - return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED; - } - } - - request = requestNetworkForFeatureLocked(netCap); - } - if (request != null) { - Log.d(TAG, "starting startUsingNetworkFeature for request " + request); - return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED; - } else { - Log.d(TAG, " request Failed"); - return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED; - } - } - - /** - * Tells the underlying networking system that the caller is finished - * using the named feature. The interpretation of {@code feature} - * is completely up to each networking implementation. - * - * <p>This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.</p> - * - * @param networkType specifies which network the request pertains to - * @param feature the name of the feature that is no longer needed - * @return an integer value representing the outcome of the request. - * The interpretation of this value is specific to each networking - * implementation+feature combination, except that the value {@code -1} - * always indicates failure. - * - * @deprecated Deprecated in favor of the cleaner - * {@link #unregisterNetworkCallback(NetworkCallback)} API. - * In {@link VERSION_CODES#M}, and above, this method is unsupported and will - * throw {@code UnsupportedOperationException} if called. - * @removed - */ - @Deprecated - public int stopUsingNetworkFeature(int networkType, String feature) { - checkLegacyRoutingApiAccess(); - NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature); - if (netCap == null) { - Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " + - feature); - return -1; - } - - if (removeRequestForFeature(netCap)) { - Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature); - } - return 1; - } - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) { - if (networkType == TYPE_MOBILE) { - switch (feature) { - case "enableCBS": - return networkCapabilitiesForType(TYPE_MOBILE_CBS); - case "enableDUN": - case "enableDUNAlways": - return networkCapabilitiesForType(TYPE_MOBILE_DUN); - case "enableFOTA": - return networkCapabilitiesForType(TYPE_MOBILE_FOTA); - case "enableHIPRI": - return networkCapabilitiesForType(TYPE_MOBILE_HIPRI); - case "enableIMS": - return networkCapabilitiesForType(TYPE_MOBILE_IMS); - case "enableMMS": - return networkCapabilitiesForType(TYPE_MOBILE_MMS); - case "enableSUPL": - return networkCapabilitiesForType(TYPE_MOBILE_SUPL); - default: - return null; - } - } else if (networkType == TYPE_WIFI && "p2p".equals(feature)) { - return networkCapabilitiesForType(TYPE_WIFI_P2P); - } - return null; - } - - private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) { - if (netCap == null) return TYPE_NONE; - if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) { - return TYPE_MOBILE_CBS; - } - if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) { - return TYPE_MOBILE_IMS; - } - if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) { - return TYPE_MOBILE_FOTA; - } - if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) { - return TYPE_MOBILE_DUN; - } - if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) { - return TYPE_MOBILE_SUPL; - } - if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) { - return TYPE_MOBILE_MMS; - } - if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) { - return TYPE_MOBILE_HIPRI; - } - if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) { - return TYPE_WIFI_P2P; - } - return TYPE_NONE; - } - - private static class LegacyRequest { - NetworkCapabilities networkCapabilities; - NetworkRequest networkRequest; - int expireSequenceNumber; - Network currentNetwork; - int delay = -1; - - private void clearDnsBinding() { - if (currentNetwork != null) { - currentNetwork = null; - setProcessDefaultNetworkForHostResolution(null); - } - } - - NetworkCallback networkCallback = new NetworkCallback() { - @Override - public void onAvailable(Network network) { - currentNetwork = network; - Log.d(TAG, "startUsingNetworkFeature got Network:" + network); - setProcessDefaultNetworkForHostResolution(network); - } - @Override - public void onLost(Network network) { - if (network.equals(currentNetwork)) clearDnsBinding(); - Log.d(TAG, "startUsingNetworkFeature lost Network:" + network); - } - }; - } - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - private static final HashMap<NetworkCapabilities, LegacyRequest> sLegacyRequests = - new HashMap<>(); - - private NetworkRequest findRequestForFeature(NetworkCapabilities netCap) { - synchronized (sLegacyRequests) { - LegacyRequest l = sLegacyRequests.get(netCap); - if (l != null) return l.networkRequest; - } - return null; - } - - private void renewRequestLocked(LegacyRequest l) { - l.expireSequenceNumber++; - Log.d(TAG, "renewing request to seqNum " + l.expireSequenceNumber); - sendExpireMsgForFeature(l.networkCapabilities, l.expireSequenceNumber, l.delay); - } - - private void expireRequest(NetworkCapabilities netCap, int sequenceNum) { - int ourSeqNum = -1; - synchronized (sLegacyRequests) { - LegacyRequest l = sLegacyRequests.get(netCap); - if (l == null) return; - ourSeqNum = l.expireSequenceNumber; - if (l.expireSequenceNumber == sequenceNum) removeRequestForFeature(netCap); - } - Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum); - } - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) { - int delay = -1; - int type = legacyTypeForNetworkCapabilities(netCap); - try { - delay = mService.getRestoreDefaultNetworkDelay(type); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - LegacyRequest l = new LegacyRequest(); - l.networkCapabilities = netCap; - l.delay = delay; - l.expireSequenceNumber = 0; - l.networkRequest = sendRequestForNetwork( - netCap, l.networkCallback, 0, REQUEST, type, getDefaultHandler()); - if (l.networkRequest == null) return null; - sLegacyRequests.put(netCap, l); - sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay); - return l.networkRequest; - } - - private void sendExpireMsgForFeature(NetworkCapabilities netCap, int seqNum, int delay) { - if (delay >= 0) { - Log.d(TAG, "sending expire msg with seqNum " + seqNum + " and delay " + delay); - CallbackHandler handler = getDefaultHandler(); - Message msg = handler.obtainMessage(EXPIRE_LEGACY_REQUEST, seqNum, 0, netCap); - handler.sendMessageDelayed(msg, delay); - } - } - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - private boolean removeRequestForFeature(NetworkCapabilities netCap) { - final LegacyRequest l; - synchronized (sLegacyRequests) { - l = sLegacyRequests.remove(netCap); - } - if (l == null) return false; - unregisterNetworkCallback(l.networkCallback); - l.clearDnsBinding(); - return true; - } - - private static final SparseIntArray sLegacyTypeToTransport = new SparseIntArray(); - static { - sLegacyTypeToTransport.put(TYPE_MOBILE, NetworkCapabilities.TRANSPORT_CELLULAR); - sLegacyTypeToTransport.put(TYPE_MOBILE_CBS, NetworkCapabilities.TRANSPORT_CELLULAR); - sLegacyTypeToTransport.put(TYPE_MOBILE_DUN, NetworkCapabilities.TRANSPORT_CELLULAR); - sLegacyTypeToTransport.put(TYPE_MOBILE_FOTA, NetworkCapabilities.TRANSPORT_CELLULAR); - sLegacyTypeToTransport.put(TYPE_MOBILE_HIPRI, NetworkCapabilities.TRANSPORT_CELLULAR); - sLegacyTypeToTransport.put(TYPE_MOBILE_IMS, NetworkCapabilities.TRANSPORT_CELLULAR); - sLegacyTypeToTransport.put(TYPE_MOBILE_MMS, NetworkCapabilities.TRANSPORT_CELLULAR); - sLegacyTypeToTransport.put(TYPE_MOBILE_SUPL, NetworkCapabilities.TRANSPORT_CELLULAR); - sLegacyTypeToTransport.put(TYPE_WIFI, NetworkCapabilities.TRANSPORT_WIFI); - sLegacyTypeToTransport.put(TYPE_WIFI_P2P, NetworkCapabilities.TRANSPORT_WIFI); - sLegacyTypeToTransport.put(TYPE_BLUETOOTH, NetworkCapabilities.TRANSPORT_BLUETOOTH); - sLegacyTypeToTransport.put(TYPE_ETHERNET, NetworkCapabilities.TRANSPORT_ETHERNET); - } - - private static final SparseIntArray sLegacyTypeToCapability = new SparseIntArray(); - static { - sLegacyTypeToCapability.put(TYPE_MOBILE_CBS, NetworkCapabilities.NET_CAPABILITY_CBS); - sLegacyTypeToCapability.put(TYPE_MOBILE_DUN, NetworkCapabilities.NET_CAPABILITY_DUN); - sLegacyTypeToCapability.put(TYPE_MOBILE_FOTA, NetworkCapabilities.NET_CAPABILITY_FOTA); - sLegacyTypeToCapability.put(TYPE_MOBILE_IMS, NetworkCapabilities.NET_CAPABILITY_IMS); - sLegacyTypeToCapability.put(TYPE_MOBILE_MMS, NetworkCapabilities.NET_CAPABILITY_MMS); - sLegacyTypeToCapability.put(TYPE_MOBILE_SUPL, NetworkCapabilities.NET_CAPABILITY_SUPL); - sLegacyTypeToCapability.put(TYPE_WIFI_P2P, NetworkCapabilities.NET_CAPABILITY_WIFI_P2P); - } - - /** - * Given a legacy type (TYPE_WIFI, ...) returns a NetworkCapabilities - * instance suitable for registering a request or callback. Throws an - * IllegalArgumentException if no mapping from the legacy type to - * NetworkCapabilities is known. - * - * @deprecated Types are deprecated. Use {@link NetworkCallback} or {@link NetworkRequest} - * to find the network instead. - * @hide - */ - public static NetworkCapabilities networkCapabilitiesForType(int type) { - final NetworkCapabilities nc = new NetworkCapabilities(); - - // Map from type to transports. - final int NOT_FOUND = -1; - final int transport = sLegacyTypeToTransport.get(type, NOT_FOUND); - Preconditions.checkArgument(transport != NOT_FOUND, "unknown legacy type: " + type); - nc.addTransportType(transport); - - // Map from type to capabilities. - nc.addCapability(sLegacyTypeToCapability.get( - type, NetworkCapabilities.NET_CAPABILITY_INTERNET)); - nc.maybeMarkCapabilitiesRestricted(); - return nc; - } - - /** @hide */ - public static class PacketKeepaliveCallback { - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public PacketKeepaliveCallback() { - } - /** The requested keepalive was successfully started. */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public void onStarted() {} - /** The keepalive was successfully stopped. */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public void onStopped() {} - /** An error occurred. */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public void onError(int error) {} - } - - /** - * Allows applications to request that the system periodically send specific packets on their - * behalf, using hardware offload to save battery power. - * - * To request that the system send keepalives, call one of the methods that return a - * {@link ConnectivityManager.PacketKeepalive} object, such as {@link #startNattKeepalive}, - * passing in a non-null callback. If the callback is successfully started, the callback's - * {@code onStarted} method will be called. If an error occurs, {@code onError} will be called, - * specifying one of the {@code ERROR_*} constants in this class. - * - * To stop an existing keepalive, call {@link PacketKeepalive#stop}. The system will call - * {@link PacketKeepaliveCallback#onStopped} if the operation was successful or - * {@link PacketKeepaliveCallback#onError} if an error occurred. - * - * @deprecated Use {@link SocketKeepalive} instead. - * - * @hide - */ - public class PacketKeepalive { - - private static final String TAG = "PacketKeepalive"; - - /** @hide */ - public static final int SUCCESS = 0; - - /** @hide */ - public static final int NO_KEEPALIVE = -1; - - /** @hide */ - public static final int BINDER_DIED = -10; - - /** The specified {@code Network} is not connected. */ - public static final int ERROR_INVALID_NETWORK = -20; - /** The specified IP addresses are invalid. For example, the specified source IP address is - * not configured on the specified {@code Network}. */ - public static final int ERROR_INVALID_IP_ADDRESS = -21; - /** The requested port is invalid. */ - public static final int ERROR_INVALID_PORT = -22; - /** The packet length is invalid (e.g., too long). */ - public static final int ERROR_INVALID_LENGTH = -23; - /** The packet transmission interval is invalid (e.g., too short). */ - public static final int ERROR_INVALID_INTERVAL = -24; - - /** The hardware does not support this request. */ - public static final int ERROR_HARDWARE_UNSUPPORTED = -30; - /** The hardware returned an error. */ - public static final int ERROR_HARDWARE_ERROR = -31; - - /** The NAT-T destination port for IPsec */ - public static final int NATT_PORT = 4500; - - /** The minimum interval in seconds between keepalive packet transmissions */ - public static final int MIN_INTERVAL = 10; - - private final Network mNetwork; - private final ISocketKeepaliveCallback mCallback; - private final ExecutorService mExecutor; - - private volatile Integer mSlot; - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public void stop() { - try { - mExecutor.execute(() -> { - try { - if (mSlot != null) { - mService.stopKeepalive(mNetwork, mSlot); - } - } catch (RemoteException e) { - Log.e(TAG, "Error stopping packet keepalive: ", e); - throw e.rethrowFromSystemServer(); - } - }); - } catch (RejectedExecutionException e) { - // The internal executor has already stopped due to previous event. - } - } - - private PacketKeepalive(Network network, PacketKeepaliveCallback callback) { - Preconditions.checkNotNull(network, "network cannot be null"); - Preconditions.checkNotNull(callback, "callback cannot be null"); - mNetwork = network; - mExecutor = Executors.newSingleThreadExecutor(); - mCallback = new ISocketKeepaliveCallback.Stub() { - @Override - public void onStarted(int slot) { - final long token = Binder.clearCallingIdentity(); - try { - mExecutor.execute(() -> { - mSlot = slot; - callback.onStarted(); - }); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void onStopped() { - final long token = Binder.clearCallingIdentity(); - try { - mExecutor.execute(() -> { - mSlot = null; - callback.onStopped(); - }); - } finally { - Binder.restoreCallingIdentity(token); - } - mExecutor.shutdown(); - } - - @Override - public void onError(int error) { - final long token = Binder.clearCallingIdentity(); - try { - mExecutor.execute(() -> { - mSlot = null; - callback.onError(error); - }); - } finally { - Binder.restoreCallingIdentity(token); - } - mExecutor.shutdown(); - } - - @Override - public void onDataReceived() { - // PacketKeepalive is only used for Nat-T keepalive and as such does not invoke - // this callback when data is received. - } - }; - } - } - - /** - * Starts an IPsec NAT-T keepalive packet with the specified parameters. - * - * @deprecated Use {@link #createSocketKeepalive} instead. - * - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public PacketKeepalive startNattKeepalive( - Network network, int intervalSeconds, PacketKeepaliveCallback callback, - InetAddress srcAddr, int srcPort, InetAddress dstAddr) { - final PacketKeepalive k = new PacketKeepalive(network, callback); - try { - mService.startNattKeepalive(network, intervalSeconds, k.mCallback, - srcAddr.getHostAddress(), srcPort, dstAddr.getHostAddress()); - } catch (RemoteException e) { - Log.e(TAG, "Error starting packet keepalive: ", e); - throw e.rethrowFromSystemServer(); - } - return k; - } - - // Construct an invalid fd. - private ParcelFileDescriptor createInvalidFd() { - final int invalidFd = -1; - return ParcelFileDescriptor.adoptFd(invalidFd); - } - - /** - * Request that keepalives be started on a IPsec NAT-T socket. - * - * @param network The {@link Network} the socket is on. - * @param socket The socket that needs to be kept alive. - * @param source The source address of the {@link UdpEncapsulationSocket}. - * @param destination The destination address of the {@link UdpEncapsulationSocket}. - * @param executor The executor on which callback will be invoked. The provided {@link Executor} - * must run callback sequentially, otherwise the order of callbacks cannot be - * guaranteed. - * @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive - * changes. Must be extended by applications that use this API. - * - * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the - * given socket. - **/ - public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network, - @NonNull UdpEncapsulationSocket socket, - @NonNull InetAddress source, - @NonNull InetAddress destination, - @NonNull @CallbackExecutor Executor executor, - @NonNull Callback callback) { - ParcelFileDescriptor dup; - try { - // Dup is needed here as the pfd inside the socket is owned by the IpSecService, - // which cannot be obtained by the app process. - dup = ParcelFileDescriptor.dup(socket.getFileDescriptor()); - } catch (IOException ignored) { - // Construct an invalid fd, so that if the user later calls start(), it will fail with - // ERROR_INVALID_SOCKET. - dup = createInvalidFd(); - } - return new NattSocketKeepalive(mService, network, dup, socket.getResourceId(), source, - destination, executor, callback); - } - - /** - * Request that keepalives be started on a IPsec NAT-T socket file descriptor. Directly called - * by system apps which don't use IpSecService to create {@link UdpEncapsulationSocket}. - * - * @param network The {@link Network} the socket is on. - * @param pfd The {@link ParcelFileDescriptor} that needs to be kept alive. The provided - * {@link ParcelFileDescriptor} must be bound to a port and the keepalives will be sent - * from that port. - * @param source The source address of the {@link UdpEncapsulationSocket}. - * @param destination The destination address of the {@link UdpEncapsulationSocket}. The - * keepalive packets will always be sent to port 4500 of the given {@code destination}. - * @param executor The executor on which callback will be invoked. The provided {@link Executor} - * must run callback sequentially, otherwise the order of callbacks cannot be - * guaranteed. - * @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive - * changes. Must be extended by applications that use this API. - * - * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the - * given socket. - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) - public @NonNull SocketKeepalive createNattKeepalive(@NonNull Network network, - @NonNull ParcelFileDescriptor pfd, - @NonNull InetAddress source, - @NonNull InetAddress destination, - @NonNull @CallbackExecutor Executor executor, - @NonNull Callback callback) { - ParcelFileDescriptor dup; - try { - // TODO: Consider remove unnecessary dup. - dup = pfd.dup(); - } catch (IOException ignored) { - // Construct an invalid fd, so that if the user later calls start(), it will fail with - // ERROR_INVALID_SOCKET. - dup = createInvalidFd(); - } - return new NattSocketKeepalive(mService, network, dup, - INVALID_RESOURCE_ID /* Unused */, source, destination, executor, callback); - } - - /** - * Request that keepalives be started on a TCP socket. - * The socket must be established. - * - * @param network The {@link Network} the socket is on. - * @param socket The socket that needs to be kept alive. - * @param executor The executor on which callback will be invoked. This implementation assumes - * the provided {@link Executor} runs the callbacks in sequence with no - * concurrency. Failing this, no guarantee of correctness can be made. It is - * the responsibility of the caller to ensure the executor provides this - * guarantee. A simple way of creating such an executor is with the standard - * tool {@code Executors.newSingleThreadExecutor}. - * @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive - * changes. Must be extended by applications that use this API. - * - * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the - * given socket. - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) - public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network, - @NonNull Socket socket, - @NonNull Executor executor, - @NonNull Callback callback) { - ParcelFileDescriptor dup; - try { - dup = ParcelFileDescriptor.fromSocket(socket); - } catch (UncheckedIOException ignored) { - // Construct an invalid fd, so that if the user later calls start(), it will fail with - // ERROR_INVALID_SOCKET. - dup = createInvalidFd(); - } - return new TcpSocketKeepalive(mService, network, dup, executor, callback); - } - - /** - * Ensure that a network route exists to deliver traffic to the specified - * host via the specified network interface. An attempt to add a route that - * already exists is ignored, but treated as successful. - * - * <p>This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.</p> - * - * @param networkType the type of the network over which traffic to the specified - * host is to be routed - * @param hostAddress the IP address of the host to which the route is desired - * @return {@code true} on success, {@code false} on failure - * - * @deprecated Deprecated in favor of the - * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, - * {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} API. - * In {@link VERSION_CODES#M}, and above, this method is unsupported and will - * throw {@code UnsupportedOperationException} if called. - * @removed - */ - @Deprecated - public boolean requestRouteToHost(int networkType, int hostAddress) { - return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress)); - } - - /** - * Ensure that a network route exists to deliver traffic to the specified - * host via the specified network interface. An attempt to add a route that - * already exists is ignored, but treated as successful. - * - * <p>This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.</p> - * - * @param networkType the type of the network over which traffic to the specified - * host is to be routed - * @param hostAddress the IP address of the host to which the route is desired - * @return {@code true} on success, {@code false} on failure - * @hide - * @deprecated Deprecated in favor of the {@link #requestNetwork} and - * {@link #bindProcessToNetwork} API. - */ - @Deprecated - @UnsupportedAppUsage - public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) { - checkLegacyRoutingApiAccess(); - try { - return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress(), - mContext.getOpPackageName(), getAttributionTag()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * @return the context's attribution tag - */ - // TODO: Remove method and replace with direct call once R code is pushed to AOSP - private @Nullable String getAttributionTag() { - return null; - } - - /** - * Returns the value of the setting for background data usage. If false, - * applications should not use the network if the application is not in the - * foreground. Developers should respect this setting, and check the value - * of this before performing any background data operations. - * <p> - * All applications that have background services that use the network - * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}. - * <p> - * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of - * background data depends on several combined factors, and this method will - * always return {@code true}. Instead, when background data is unavailable, - * {@link #getActiveNetworkInfo()} will now appear disconnected. - * - * @return Whether background data usage is allowed. - */ - @Deprecated - public boolean getBackgroundDataSetting() { - // assume that background data is allowed; final authority is - // NetworkInfo which may be blocked. - return true; - } - - /** - * Sets the value of the setting for background data usage. - * - * @param allowBackgroundData Whether an application should use data while - * it is in the background. - * - * @attr ref android.Manifest.permission#CHANGE_BACKGROUND_DATA_SETTING - * @see #getBackgroundDataSetting() - * @hide - */ - @Deprecated - @UnsupportedAppUsage - public void setBackgroundDataSetting(boolean allowBackgroundData) { - // ignored - } - - /** - * @hide - * @deprecated Talk to TelephonyManager directly - */ - @Deprecated - @UnsupportedAppUsage - public boolean getMobileDataEnabled() { - TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); - if (tm != null) { - int subId = SubscriptionManager.getDefaultDataSubscriptionId(); - Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId); - boolean retVal = tm.createForSubscriptionId(subId).isDataEnabled(); - Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId - + " retVal=" + retVal); - return retVal; - } - Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false"); - return false; - } - - /** - * Callback for use with {@link ConnectivityManager#addDefaultNetworkActiveListener} - * to find out when the system default network has gone in to a high power state. - */ - public interface OnNetworkActiveListener { - /** - * Called on the main thread of the process to report that the current data network - * has become active, and it is now a good time to perform any pending network - * operations. Note that this listener only tells you when the network becomes - * active; if at any other time you want to know whether it is active (and thus okay - * to initiate network traffic), you can retrieve its instantaneous state with - * {@link ConnectivityManager#isDefaultNetworkActive}. - */ - void onNetworkActive(); - } - - private INetworkManagementService getNetworkManagementService() { - synchronized (this) { - if (mNMService != null) { - return mNMService; - } - IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); - mNMService = INetworkManagementService.Stub.asInterface(b); - return mNMService; - } - } - - private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener> - mNetworkActivityListeners = new ArrayMap<>(); - - /** - * Start listening to reports when the system's default data network is active, meaning it is - * a good time to perform network traffic. Use {@link #isDefaultNetworkActive()} - * to determine the current state of the system's default network after registering the - * listener. - * <p> - * If the process default network has been set with - * {@link ConnectivityManager#bindProcessToNetwork} this function will not - * reflect the process's default, but the system default. - * - * @param l The listener to be told when the network is active. - */ - public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) { - INetworkActivityListener rl = new INetworkActivityListener.Stub() { - @Override - public void onNetworkActive() throws RemoteException { - l.onNetworkActive(); - } - }; - - try { - getNetworkManagementService().registerNetworkActivityListener(rl); - mNetworkActivityListeners.put(l, rl); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Remove network active listener previously registered with - * {@link #addDefaultNetworkActiveListener}. - * - * @param l Previously registered listener. - */ - public void removeDefaultNetworkActiveListener(@NonNull OnNetworkActiveListener l) { - INetworkActivityListener rl = mNetworkActivityListeners.get(l); - Preconditions.checkArgument(rl != null, "Listener was not registered."); - try { - getNetworkManagementService().unregisterNetworkActivityListener(rl); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Return whether the data network is currently active. An active network means that - * it is currently in a high power state for performing data transmission. On some - * types of networks, it may be expensive to move and stay in such a state, so it is - * more power efficient to batch network traffic together when the radio is already in - * this state. This method tells you whether right now is currently a good time to - * initiate network traffic, as the network is already active. - */ - public boolean isDefaultNetworkActive() { - try { - return getNetworkManagementService().isNetworkActive(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * {@hide} - */ - public ConnectivityManager(Context context, IConnectivityManager service) { - mContext = Preconditions.checkNotNull(context, "missing context"); - mService = Preconditions.checkNotNull(service, "missing IConnectivityManager"); - mTetheringManager = (TetheringManager) mContext.getSystemService(Context.TETHERING_SERVICE); - sInstance = this; - } - - /** {@hide} */ - @UnsupportedAppUsage - public static ConnectivityManager from(Context context) { - return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - } - - /** @hide */ - public NetworkRequest getDefaultRequest() { - try { - // This is not racy as the default request is final in ConnectivityService. - return mService.getDefaultRequest(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /* TODO: These permissions checks don't belong in client-side code. Move them to - * services.jar, possibly in com.android.server.net. */ - - /** {@hide} */ - public static final void enforceChangePermission(Context context, - String callingPkg, String callingAttributionTag) { - int uid = Binder.getCallingUid(); - checkAndNoteChangeNetworkStateOperation(context, uid, callingPkg, - callingAttributionTag, true /* throwException */); - } - - /** - * Check if the package is a allowed to change the network state. This also accounts that such - * an access happened. - * - * @return {@code true} iff the package is allowed to change the network state. - */ - // TODO: Remove method and replace with direct call once R code is pushed to AOSP - private static boolean checkAndNoteChangeNetworkStateOperation(@NonNull Context context, - int uid, @NonNull String callingPackage, @Nullable String callingAttributionTag, - boolean throwException) { - return Settings.checkAndNoteChangeNetworkStateOperation(context, uid, callingPackage, - throwException); - } - - /** - * Check if the package is a allowed to write settings. This also accounts that such an access - * happened. - * - * @return {@code true} iff the package is allowed to write settings. - */ - // TODO: Remove method and replace with direct call once R code is pushed to AOSP - private static boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid, - @NonNull String callingPackage, @Nullable String callingAttributionTag, - boolean throwException) { - return Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPackage, - throwException); - } - - /** - * @deprecated - use getSystemService. This is a kludge to support static access in certain - * situations where a Context pointer is unavailable. - * @hide - */ - @Deprecated - static ConnectivityManager getInstanceOrNull() { - return sInstance; - } - - /** - * @deprecated - use getSystemService. This is a kludge to support static access in certain - * situations where a Context pointer is unavailable. - * @hide - */ - @Deprecated - @UnsupportedAppUsage - private static ConnectivityManager getInstance() { - if (getInstanceOrNull() == null) { - throw new IllegalStateException("No ConnectivityManager yet constructed"); - } - return getInstanceOrNull(); - } - - /** - * Get the set of tetherable, available interfaces. This list is limited by - * device configuration and current interface existence. - * - * @return an array of 0 or more Strings of tetherable interface names. - * - * @deprecated Use {@link TetheringEventCallback#onTetherableInterfacesChanged(List)} instead. - * {@hide} - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage - @Deprecated - public String[] getTetherableIfaces() { - return mTetheringManager.getTetherableIfaces(); - } - - /** - * Get the set of tethered interfaces. - * - * @return an array of 0 or more String of currently tethered interface names. - * - * @deprecated Use {@link TetheringEventCallback#onTetherableInterfacesChanged(List)} instead. - * {@hide} - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage - @Deprecated - public String[] getTetheredIfaces() { - return mTetheringManager.getTetheredIfaces(); - } - - /** - * Get the set of interface names which attempted to tether but - * failed. Re-attempting to tether may cause them to reset to the Tethered - * state. Alternatively, causing the interface to be destroyed and recreated - * may cause them to reset to the available state. - * {@link ConnectivityManager#getLastTetherError} can be used to get more - * information on the cause of the errors. - * - * @return an array of 0 or more String indicating the interface names - * which failed to tether. - * - * @deprecated Use {@link TetheringEventCallback#onError(String, int)} instead. - * {@hide} - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage - @Deprecated - public String[] getTetheringErroredIfaces() { - return mTetheringManager.getTetheringErroredIfaces(); - } - - /** - * Get the set of tethered dhcp ranges. - * - * @deprecated This method is not supported. - * TODO: remove this function when all of clients are removed. - * {@hide} - */ - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - @Deprecated - public String[] getTetheredDhcpRanges() { - throw new UnsupportedOperationException("getTetheredDhcpRanges is not supported"); - } - - /** - * Attempt to tether the named interface. This will setup a dhcp server - * on the interface, forward and NAT IP packets and forward DNS requests - * to the best active upstream network interface. Note that if no upstream - * IP network interface is available, dhcp will still run and traffic will be - * allowed between the tethered devices and this device, though upstream net - * access will of course fail until an upstream network interface becomes - * active. - * - * <p>This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.</p> - * - * <p>WARNING: New clients should not use this function. The only usages should be in PanService - * and WifiStateMachine which need direct access. All other clients should use - * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning - * logic.</p> - * - * @param iface the interface name to tether. - * @return error a {@code TETHER_ERROR} value indicating success or failure type - * @deprecated Use {@link TetheringManager#startTethering} instead - * - * {@hide} - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @Deprecated - public int tether(String iface) { - return mTetheringManager.tether(iface); - } - - /** - * Stop tethering the named interface. - * - * <p>This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.</p> - * - * <p>WARNING: New clients should not use this function. The only usages should be in PanService - * and WifiStateMachine which need direct access. All other clients should use - * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning - * logic.</p> - * - * @param iface the interface name to untether. - * @return error a {@code TETHER_ERROR} value indicating success or failure type - * - * {@hide} - */ - @UnsupportedAppUsage - @Deprecated - public int untether(String iface) { - return mTetheringManager.untether(iface); - } - - /** - * Check if the device allows for tethering. It may be disabled via - * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or - * due to device configuration. - * - * <p>If this app does not have permission to use this API, it will always - * return false rather than throw an exception.</p> - * - * <p>If the device has a hotspot provisioning app, the caller is required to hold the - * {@link android.Manifest.permission.TETHER_PRIVILEGED} permission.</p> - * - * <p>Otherwise, this method requires the caller to hold the ability to modify system - * settings as determined by {@link android.provider.Settings.System#canWrite}.</p> - * - * @return a boolean - {@code true} indicating Tethering is supported. - * - * @deprecated Use {@link TetheringEventCallback#onTetheringSupported(boolean)} instead. - * {@hide} - */ - @SystemApi - @RequiresPermission(anyOf = {android.Manifest.permission.TETHER_PRIVILEGED, - android.Manifest.permission.WRITE_SETTINGS}) - public boolean isTetheringSupported() { - return mTetheringManager.isTetheringSupported(); - } - - /** - * Callback for use with {@link #startTethering} to find out whether tethering succeeded. - * - * @deprecated Use {@link TetheringManager.StartTetheringCallback} instead. - * @hide - */ - @SystemApi - @Deprecated - public static abstract class OnStartTetheringCallback { - /** - * Called when tethering has been successfully started. - */ - public void onTetheringStarted() {} - - /** - * Called when starting tethering failed. - */ - public void onTetheringFailed() {} - } - - /** - * Convenient overload for - * {@link #startTethering(int, boolean, OnStartTetheringCallback, Handler)} which passes a null - * handler to run on the current thread's {@link Looper}. - * - * @deprecated Use {@link TetheringManager#startTethering} instead. - * @hide - */ - @SystemApi - @Deprecated - @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) - public void startTethering(int type, boolean showProvisioningUi, - final OnStartTetheringCallback callback) { - startTethering(type, showProvisioningUi, callback, null); - } - - /** - * Runs tether provisioning for the given type if needed and then starts tethering if - * the check succeeds. If no carrier provisioning is required for tethering, tethering is - * enabled immediately. If provisioning fails, tethering will not be enabled. It also - * schedules tether provisioning re-checks if appropriate. - * - * @param type The type of tethering to start. Must be one of - * {@link ConnectivityManager.TETHERING_WIFI}, - * {@link ConnectivityManager.TETHERING_USB}, or - * {@link ConnectivityManager.TETHERING_BLUETOOTH}. - * @param showProvisioningUi a boolean indicating to show the provisioning app UI if there - * is one. This should be true the first time this function is called and also any time - * the user can see this UI. It gives users information from their carrier about the - * check failing and how they can sign up for tethering if possible. - * @param callback an {@link OnStartTetheringCallback} which will be called to notify the caller - * of the result of trying to tether. - * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. - * - * @deprecated Use {@link TetheringManager#startTethering} instead. - * @hide - */ - @SystemApi - @Deprecated - @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) - public void startTethering(int type, boolean showProvisioningUi, - final OnStartTetheringCallback callback, Handler handler) { - Preconditions.checkNotNull(callback, "OnStartTetheringCallback cannot be null."); - - final Executor executor = new Executor() { - @Override - public void execute(Runnable command) { - if (handler == null) { - command.run(); - } else { - handler.post(command); - } - } - }; - - final StartTetheringCallback tetheringCallback = new StartTetheringCallback() { - @Override - public void onTetheringStarted() { - callback.onTetheringStarted(); - } - - @Override - public void onTetheringFailed(final int error) { - callback.onTetheringFailed(); - } - }; - - final TetheringRequest request = new TetheringRequest.Builder(type) - .setShouldShowEntitlementUi(showProvisioningUi).build(); - - mTetheringManager.startTethering(request, executor, tetheringCallback); - } - - /** - * Stops tethering for the given type. Also cancels any provisioning rechecks for that type if - * applicable. - * - * @param type The type of tethering to stop. Must be one of - * {@link ConnectivityManager.TETHERING_WIFI}, - * {@link ConnectivityManager.TETHERING_USB}, or - * {@link ConnectivityManager.TETHERING_BLUETOOTH}. - * - * @deprecated Use {@link TetheringManager#stopTethering} instead. - * @hide - */ - @SystemApi - @Deprecated - @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) - public void stopTethering(int type) { - mTetheringManager.stopTethering(type); - } - - /** - * Callback for use with {@link registerTetheringEventCallback} to find out tethering - * upstream status. - * - * @deprecated Use {@link TetheringManager#OnTetheringEventCallback} instead. - * @hide - */ - @SystemApi - @Deprecated - public abstract static class OnTetheringEventCallback { - - /** - * Called when tethering upstream changed. This can be called multiple times and can be - * called any time. - * - * @param network the {@link Network} of tethering upstream. Null means tethering doesn't - * have any upstream. - */ - public void onUpstreamChanged(@Nullable Network network) {} - } - - @GuardedBy("mTetheringEventCallbacks") - private final ArrayMap<OnTetheringEventCallback, TetheringEventCallback> - mTetheringEventCallbacks = new ArrayMap<>(); - - /** - * Start listening to tethering change events. Any new added callback will receive the last - * tethering status right away. If callback is registered when tethering has no upstream or - * disabled, {@link OnTetheringEventCallback#onUpstreamChanged} will immediately be called - * with a null argument. The same callback object cannot be registered twice. - * - * @param executor the executor on which callback will be invoked. - * @param callback the callback to be called when tethering has change events. - * - * @deprecated Use {@link TetheringManager#registerTetheringEventCallback} instead. - * @hide - */ - @SystemApi - @Deprecated - @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) - public void registerTetheringEventCallback( - @NonNull @CallbackExecutor Executor executor, - @NonNull final OnTetheringEventCallback callback) { - Preconditions.checkNotNull(callback, "OnTetheringEventCallback cannot be null."); - - final TetheringEventCallback tetherCallback = - new TetheringEventCallback() { - @Override - public void onUpstreamChanged(@Nullable Network network) { - callback.onUpstreamChanged(network); - } - }; - - synchronized (mTetheringEventCallbacks) { - mTetheringEventCallbacks.put(callback, tetherCallback); - mTetheringManager.registerTetheringEventCallback(executor, tetherCallback); - } - } - - /** - * Remove tethering event callback previously registered with - * {@link #registerTetheringEventCallback}. - * - * @param callback previously registered callback. - * - * @deprecated Use {@link TetheringManager#unregisterTetheringEventCallback} instead. - * @hide - */ - @SystemApi - @Deprecated - @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) - public void unregisterTetheringEventCallback( - @NonNull final OnTetheringEventCallback callback) { - Objects.requireNonNull(callback, "The callback must be non-null"); - synchronized (mTetheringEventCallbacks) { - final TetheringEventCallback tetherCallback = - mTetheringEventCallbacks.remove(callback); - mTetheringManager.unregisterTetheringEventCallback(tetherCallback); - } - } - - - /** - * Get the list of regular expressions that define any tetherable - * USB network interfaces. If USB tethering is not supported by the - * device, this list should be empty. - * - * @return an array of 0 or more regular expression Strings defining - * what interfaces are considered tetherable usb interfaces. - * - * @deprecated Use {@link TetheringEventCallback#onTetherableInterfaceRegexpsChanged} instead. - * {@hide} - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage - @Deprecated - public String[] getTetherableUsbRegexs() { - return mTetheringManager.getTetherableUsbRegexs(); - } - - /** - * Get the list of regular expressions that define any tetherable - * Wifi network interfaces. If Wifi tethering is not supported by the - * device, this list should be empty. - * - * @return an array of 0 or more regular expression Strings defining - * what interfaces are considered tetherable wifi interfaces. - * - * @deprecated Use {@link TetheringEventCallback#onTetherableInterfaceRegexpsChanged} instead. - * {@hide} - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage - @Deprecated - public String[] getTetherableWifiRegexs() { - return mTetheringManager.getTetherableWifiRegexs(); - } - - /** - * Get the list of regular expressions that define any tetherable - * Bluetooth network interfaces. If Bluetooth tethering is not supported by the - * device, this list should be empty. - * - * @return an array of 0 or more regular expression Strings defining - * what interfaces are considered tetherable bluetooth interfaces. - * - * @deprecated Use {@link TetheringEventCallback#onTetherableInterfaceRegexpsChanged( - *TetheringManager.TetheringInterfaceRegexps)} instead. - * {@hide} - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage - @Deprecated - public String[] getTetherableBluetoothRegexs() { - return mTetheringManager.getTetherableBluetoothRegexs(); - } - - /** - * Attempt to both alter the mode of USB and Tethering of USB. A - * utility method to deal with some of the complexity of USB - will - * attempt to switch to Rndis and subsequently tether the resulting - * interface on {@code true} or turn off tethering and switch off - * Rndis on {@code false}. - * - * <p>This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.</p> - * - * @param enable a boolean - {@code true} to enable tethering - * @return error a {@code TETHER_ERROR} value indicating success or failure type - * @deprecated Use {@link TetheringManager#startTethering} instead - * - * {@hide} - */ - @UnsupportedAppUsage - @Deprecated - public int setUsbTethering(boolean enable) { - return mTetheringManager.setUsbTethering(enable); - } - - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_NO_ERROR}. - * {@hide} - */ - @SystemApi - @Deprecated - public static final int TETHER_ERROR_NO_ERROR = TetheringManager.TETHER_ERROR_NO_ERROR; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_UNKNOWN_IFACE}. - * {@hide} - */ - @Deprecated - public static final int TETHER_ERROR_UNKNOWN_IFACE = - TetheringManager.TETHER_ERROR_UNKNOWN_IFACE; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_SERVICE_UNAVAIL}. - * {@hide} - */ - @Deprecated - public static final int TETHER_ERROR_SERVICE_UNAVAIL = - TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_UNSUPPORTED}. - * {@hide} - */ - @Deprecated - public static final int TETHER_ERROR_UNSUPPORTED = TetheringManager.TETHER_ERROR_UNSUPPORTED; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_UNAVAIL_IFACE}. - * {@hide} - */ - @Deprecated - public static final int TETHER_ERROR_UNAVAIL_IFACE = - TetheringManager.TETHER_ERROR_UNAVAIL_IFACE; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_INTERNAL_ERROR}. - * {@hide} - */ - @Deprecated - public static final int TETHER_ERROR_MASTER_ERROR = - TetheringManager.TETHER_ERROR_INTERNAL_ERROR; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_TETHER_IFACE_ERROR}. - * {@hide} - */ - @Deprecated - public static final int TETHER_ERROR_TETHER_IFACE_ERROR = - TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_UNTETHER_IFACE_ERROR}. - * {@hide} - */ - @Deprecated - public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = - TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_ENABLE_FORWARDING_ERROR}. - * {@hide} - */ - @Deprecated - public static final int TETHER_ERROR_ENABLE_NAT_ERROR = - TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_DISABLE_FORWARDING_ERROR}. - * {@hide} - */ - @Deprecated - public static final int TETHER_ERROR_DISABLE_NAT_ERROR = - TetheringManager.TETHER_ERROR_DISABLE_FORWARDING_ERROR; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_IFACE_CFG_ERROR}. - * {@hide} - */ - @Deprecated - public static final int TETHER_ERROR_IFACE_CFG_ERROR = - TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_PROVISIONING_FAILED}. - * {@hide} - */ - @SystemApi - @Deprecated - public static final int TETHER_ERROR_PROVISION_FAILED = - TetheringManager.TETHER_ERROR_PROVISIONING_FAILED; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_DHCPSERVER_ERROR}. - * {@hide} - */ - @Deprecated - public static final int TETHER_ERROR_DHCPSERVER_ERROR = - TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR; - /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_ENTITLEMENT_UNKNOWN}. - * {@hide} - */ - @SystemApi - @Deprecated - public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN = - TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN; - - /** - * Get a more detailed error code after a Tethering or Untethering - * request asynchronously failed. - * - * @param iface The name of the interface of interest - * @return error The error code of the last error tethering or untethering the named - * interface - * - * @deprecated Use {@link TetheringEventCallback#onError(String, int)} instead. - * {@hide} - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @Deprecated - public int getLastTetherError(String iface) { - int error = mTetheringManager.getLastTetherError(iface); - if (error == TetheringManager.TETHER_ERROR_UNKNOWN_TYPE) { - // TETHER_ERROR_UNKNOWN_TYPE was introduced with TetheringManager and has never been - // returned by ConnectivityManager. Convert it to the legacy TETHER_ERROR_UNKNOWN_IFACE - // instead. - error = TetheringManager.TETHER_ERROR_UNKNOWN_IFACE; - } - return error; - } - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(value = { - TETHER_ERROR_NO_ERROR, - TETHER_ERROR_PROVISION_FAILED, - TETHER_ERROR_ENTITLEMENT_UNKONWN, - }) - public @interface EntitlementResultCode { - } - - /** - * Callback for use with {@link #getLatestTetheringEntitlementResult} to find out whether - * entitlement succeeded. - * - * @deprecated Use {@link TetheringManager#OnTetheringEntitlementResultListener} instead. - * @hide - */ - @SystemApi - @Deprecated - public interface OnTetheringEntitlementResultListener { - /** - * Called to notify entitlement result. - * - * @param resultCode an int value of entitlement result. It may be one of - * {@link #TETHER_ERROR_NO_ERROR}, - * {@link #TETHER_ERROR_PROVISION_FAILED}, or - * {@link #TETHER_ERROR_ENTITLEMENT_UNKONWN}. - */ - void onTetheringEntitlementResult(@EntitlementResultCode int resultCode); - } - - /** - * Get the last value of the entitlement check on this downstream. If the cached value is - * {@link #TETHER_ERROR_NO_ERROR} or showEntitlementUi argument is false, it just return the - * cached value. Otherwise, a UI-based entitlement check would be performed. It is not - * guaranteed that the UI-based entitlement check will complete in any specific time period - * and may in fact never complete. Any successful entitlement check the platform performs for - * any reason will update the cached value. - * - * @param type the downstream type of tethering. Must be one of - * {@link #TETHERING_WIFI}, - * {@link #TETHERING_USB}, or - * {@link #TETHERING_BLUETOOTH}. - * @param showEntitlementUi a boolean indicating whether to run UI-based entitlement check. - * @param executor the executor on which callback will be invoked. - * @param listener an {@link OnTetheringEntitlementResultListener} which will be called to - * notify the caller of the result of entitlement check. The listener may be called zero - * or one time. - * @deprecated Use {@link TetheringManager#requestLatestTetheringEntitlementResult} instead. - * {@hide} - */ - @SystemApi - @Deprecated - @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) - public void getLatestTetheringEntitlementResult(int type, boolean showEntitlementUi, - @NonNull @CallbackExecutor Executor executor, - @NonNull final OnTetheringEntitlementResultListener listener) { - Preconditions.checkNotNull(listener, "TetheringEntitlementResultListener cannot be null."); - ResultReceiver wrappedListener = new ResultReceiver(null) { - @Override - protected void onReceiveResult(int resultCode, Bundle resultData) { - Binder.withCleanCallingIdentity(() -> - executor.execute(() -> { - listener.onTetheringEntitlementResult(resultCode); - })); - } - }; - - mTetheringManager.requestLatestTetheringEntitlementResult(type, wrappedListener, - showEntitlementUi); - } - - /** - * Report network connectivity status. This is currently used only - * to alter status bar UI. - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#STATUS_BAR}. - * - * @param networkType The type of network you want to report on - * @param percentage The quality of the connection 0 is bad, 100 is good - * @deprecated Types are deprecated. Use {@link #reportNetworkConnectivity} instead. - * {@hide} - */ - public void reportInetCondition(int networkType, int percentage) { - printStackTrace(); - try { - mService.reportInetCondition(networkType, percentage); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Report a problem network to the framework. This provides a hint to the system - * that there might be connectivity problems on this network and may cause - * the framework to re-evaluate network connectivity and/or switch to another - * network. - * - * @param network The {@link Network} the application was attempting to use - * or {@code null} to indicate the current default network. - * @deprecated Use {@link #reportNetworkConnectivity} which allows reporting both - * working and non-working connectivity. - */ - @Deprecated - public void reportBadNetwork(@Nullable Network network) { - printStackTrace(); - try { - // One of these will be ignored because it matches system's current state. - // The other will trigger the necessary reevaluation. - mService.reportNetworkConnectivity(network, true); - mService.reportNetworkConnectivity(network, false); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Report to the framework whether a network has working connectivity. - * This provides a hint to the system that a particular network is providing - * working connectivity or not. In response the framework may re-evaluate - * the network's connectivity and might take further action thereafter. - * - * @param network The {@link Network} the application was attempting to use - * or {@code null} to indicate the current default network. - * @param hasConnectivity {@code true} if the application was able to successfully access the - * Internet using {@code network} or {@code false} if not. - */ - public void reportNetworkConnectivity(@Nullable Network network, boolean hasConnectivity) { - printStackTrace(); - try { - mService.reportNetworkConnectivity(network, hasConnectivity); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Set a network-independent global http proxy. This is not normally what you want - * for typical HTTP proxies - they are general network dependent. However if you're - * doing something unusual like general internal filtering this may be useful. On - * a private network where the proxy is not accessible, you may break HTTP using this. - * - * @param p A {@link ProxyInfo} object defining the new global - * HTTP proxy. A {@code null} value will clear the global HTTP proxy. - * @hide - */ - @RequiresPermission(android.Manifest.permission.NETWORK_STACK) - public void setGlobalProxy(ProxyInfo p) { - try { - mService.setGlobalProxy(p); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Retrieve any network-independent global HTTP proxy. - * - * @return {@link ProxyInfo} for the current global HTTP proxy or {@code null} - * if no global HTTP proxy is set. - * @hide - */ - public ProxyInfo getGlobalProxy() { - try { - return mService.getGlobalProxy(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Retrieve the global HTTP proxy, or if no global HTTP proxy is set, a - * network-specific HTTP proxy. If {@code network} is null, the - * network-specific proxy returned is the proxy of the default active - * network. - * - * @return {@link ProxyInfo} for the current global HTTP proxy, or if no - * global HTTP proxy is set, {@code ProxyInfo} for {@code network}, - * or when {@code network} is {@code null}, - * the {@code ProxyInfo} for the default active network. Returns - * {@code null} when no proxy applies or the caller doesn't have - * permission to use {@code network}. - * @hide - */ - public ProxyInfo getProxyForNetwork(Network network) { - try { - return mService.getProxyForNetwork(network); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Get the current default HTTP proxy settings. If a global proxy is set it will be returned, - * otherwise if this process is bound to a {@link Network} using - * {@link #bindProcessToNetwork} then that {@code Network}'s proxy is returned, otherwise - * the default network's proxy is returned. - * - * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no - * HTTP proxy is active. - */ - @Nullable - public ProxyInfo getDefaultProxy() { - return getProxyForNetwork(getBoundNetworkForProcess()); - } - - /** - * Returns true if the hardware supports the given network type - * else it returns false. This doesn't indicate we have coverage - * or are authorized onto a network, just whether or not the - * hardware supports it. For example a GSM phone without a SIM - * should still return {@code true} for mobile data, but a wifi only - * tablet would return {@code false}. - * - * @param networkType The network type we'd like to check - * @return {@code true} if supported, else {@code false} - * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead. - * @hide - */ - @Deprecated - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) - public boolean isNetworkSupported(int networkType) { - try { - return mService.isNetworkSupported(networkType); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns if the currently active data network is metered. A network is - * classified as metered when the user is sensitive to heavy data usage on - * that connection due to monetary costs, data limitations or - * battery/performance issues. You should check this before doing large - * data transfers, and warn the user or delay the operation until another - * network is available. - * - * @return {@code true} if large transfers should be avoided, otherwise - * {@code false}. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public boolean isActiveNetworkMetered() { - try { - return mService.isActiveNetworkMetered(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * If the LockdownVpn mechanism is enabled, updates the vpn - * with a reload of its profile. - * - * @return a boolean with {@code} indicating success - * - * <p>This method can only be called by the system UID - * {@hide} - */ - public boolean updateLockdownVpn() { - try { - return mService.updateLockdownVpn(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Set sign in error notification to visible or invisible - * - * @hide - * @deprecated Doesn't properly deal with multiple connected networks of the same type. - */ - @Deprecated - public void setProvisioningNotificationVisible(boolean visible, int networkType, - String action) { - try { - mService.setProvisioningNotificationVisible(visible, networkType, action); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Set the value for enabling/disabling airplane mode - * - * @param enable whether to enable airplane mode or not - * - * @hide - */ - @RequiresPermission(anyOf = { - android.Manifest.permission.NETWORK_AIRPLANE_MODE, - android.Manifest.permission.NETWORK_SETTINGS, - android.Manifest.permission.NETWORK_SETUP_WIZARD, - android.Manifest.permission.NETWORK_STACK}) - @SystemApi - public void setAirplaneMode(boolean enable) { - try { - mService.setAirplaneMode(enable); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** {@hide} - returns the factory serial number */ - @UnsupportedAppUsage - @RequiresPermission(anyOf = { - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_FACTORY}) - public int registerNetworkFactory(Messenger messenger, String name) { - try { - return mService.registerNetworkFactory(messenger, name); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** {@hide} */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - @RequiresPermission(anyOf = { - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_FACTORY}) - public void unregisterNetworkFactory(Messenger messenger) { - try { - mService.unregisterNetworkFactory(messenger); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Registers the specified {@link NetworkProvider}. - * Each listener must only be registered once. The listener can be unregistered with - * {@link #unregisterNetworkProvider}. - * - * @param provider the provider to register - * @return the ID of the provider. This ID must be used by the provider when registering - * {@link android.net.NetworkAgent}s. - * @hide - */ - @SystemApi - @RequiresPermission(anyOf = { - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_FACTORY}) - public int registerNetworkProvider(@NonNull NetworkProvider provider) { - if (provider.getProviderId() != NetworkProvider.ID_NONE) { - throw new IllegalStateException("NetworkProviders can only be registered once"); - } - - try { - int providerId = mService.registerNetworkProvider(provider.getMessenger(), - provider.getName()); - provider.setProviderId(providerId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - return provider.getProviderId(); - } - - /** - * Unregisters the specified NetworkProvider. - * - * @param provider the provider to unregister - * @hide - */ - @SystemApi - @RequiresPermission(anyOf = { - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_FACTORY}) - public void unregisterNetworkProvider(@NonNull NetworkProvider provider) { - try { - mService.unregisterNetworkProvider(provider.getMessenger()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - provider.setProviderId(NetworkProvider.ID_NONE); - } - - - /** @hide exposed via the NetworkProvider class. */ - @RequiresPermission(anyOf = { - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_FACTORY}) - public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { - try { - mService.declareNetworkRequestUnfulfillable(request); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - // TODO : remove this method. It is a stopgap measure to help sheperding a number - // of dependent changes that would conflict throughout the automerger graph. Having this - // temporarily helps with the process of going through with all these dependent changes across - // the entire tree. - /** - * @hide - * Register a NetworkAgent with ConnectivityService. - * @return Network corresponding to NetworkAgent. - */ - @RequiresPermission(anyOf = { - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_FACTORY}) - public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp, - NetworkCapabilities nc, int score, NetworkAgentConfig config) { - return registerNetworkAgent(na, ni, lp, nc, score, config, NetworkProvider.ID_NONE); - } - - /** - * @hide - * Register a NetworkAgent with ConnectivityService. - * @return Network corresponding to NetworkAgent. - */ - @RequiresPermission(anyOf = { - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_FACTORY}) - public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp, - NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) { - try { - return mService.registerNetworkAgent(na, ni, lp, nc, score, config, providerId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Base class for {@code NetworkRequest} callbacks. Used for notifications about network - * changes. Should be extended by applications wanting notifications. - * - * A {@code NetworkCallback} is registered by calling - * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, - * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)}, - * or {@link #registerDefaultNetworkCallback(NetworkCallback)}. A {@code NetworkCallback} is - * unregistered by calling {@link #unregisterNetworkCallback(NetworkCallback)}. - * A {@code NetworkCallback} should be registered at most once at any time. - * A {@code NetworkCallback} that has been unregistered can be registered again. - */ - public static class NetworkCallback { - /** - * Called when the framework connects to a new network to evaluate whether it satisfies this - * request. If evaluation succeeds, this callback may be followed by an {@link #onAvailable} - * callback. There is no guarantee that this new network will satisfy any requests, or that - * the network will stay connected for longer than the time necessary to evaluate it. - * <p> - * Most applications <b>should not</b> act on this callback, and should instead use - * {@link #onAvailable}. This callback is intended for use by applications that can assist - * the framework in properly evaluating the network — for example, an application that - * can automatically log in to a captive portal without user intervention. - * - * @param network The {@link Network} of the network that is being evaluated. - * - * @hide - */ - public void onPreCheck(@NonNull Network network) {} - - /** - * Called when the framework connects and has declared a new network ready for use. - * This callback may be called more than once if the {@link Network} that is - * satisfying the request changes. - * - * @param network The {@link Network} of the satisfying network. - * @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network. - * @param linkProperties The {@link LinkProperties} of the satisfying network. - * @param blocked Whether access to the {@link Network} is blocked due to system policy. - * @hide - */ - public void onAvailable(@NonNull Network network, - @NonNull NetworkCapabilities networkCapabilities, - @NonNull LinkProperties linkProperties, boolean blocked) { - // Internally only this method is called when a new network is available, and - // it calls the callback in the same way and order that older versions used - // to call so as not to change the behavior. - onAvailable(network); - if (!networkCapabilities.hasCapability( - NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) { - onNetworkSuspended(network); - } - onCapabilitiesChanged(network, networkCapabilities); - onLinkPropertiesChanged(network, linkProperties); - onBlockedStatusChanged(network, blocked); - } - - /** - * Called when the framework connects and has declared a new network ready for use. - * - * <p>For callbacks registered with {@link #registerNetworkCallback}, multiple networks may - * be available at the same time, and onAvailable will be called for each of these as they - * appear. - * - * <p>For callbacks registered with {@link #requestNetwork} and - * {@link #registerDefaultNetworkCallback}, this means the network passed as an argument - * is the new best network for this request and is now tracked by this callback ; this - * callback will no longer receive method calls about other networks that may have been - * passed to this method previously. The previously-best network may have disconnected, or - * it may still be around and the newly-best network may simply be better. - * - * <p>Starting with {@link android.os.Build.VERSION_CODES#O}, this will always immediately - * be followed by a call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} - * then by a call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}, and a call - * to {@link #onBlockedStatusChanged(Network, boolean)}. - * - * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or - * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in - * this callback as this is prone to race conditions (there is no guarantee the objects - * returned by these methods will be current). Instead, wait for a call to - * {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} and - * {@link #onLinkPropertiesChanged(Network, LinkProperties)} whose arguments are guaranteed - * to be well-ordered with respect to other callbacks. - * - * @param network The {@link Network} of the satisfying network. - */ - public void onAvailable(@NonNull Network network) {} - - /** - * Called when the network is about to be lost, typically because there are no outstanding - * requests left for it. This may be paired with a {@link NetworkCallback#onAvailable} call - * with the new replacement network for graceful handover. This method is not guaranteed - * to be called before {@link NetworkCallback#onLost} is called, for example in case a - * network is suddenly disconnected. - * - * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or - * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in - * this callback as this is prone to race conditions ; calling these methods while in a - * callback may return an outdated or even a null object. - * - * @param network The {@link Network} that is about to be lost. - * @param maxMsToLive The time in milliseconds the system intends to keep the network - * connected for graceful handover; note that the network may still - * suffer a hard loss at any time. - */ - public void onLosing(@NonNull Network network, int maxMsToLive) {} - - /** - * Called when a network disconnects or otherwise no longer satisfies this request or - * callback. - * - * <p>If the callback was registered with requestNetwork() or - * registerDefaultNetworkCallback(), it will only be invoked against the last network - * returned by onAvailable() when that network is lost and no other network satisfies - * the criteria of the request. - * - * <p>If the callback was registered with registerNetworkCallback() it will be called for - * each network which no longer satisfies the criteria of the callback. - * - * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or - * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in - * this callback as this is prone to race conditions ; calling these methods while in a - * callback may return an outdated or even a null object. - * - * @param network The {@link Network} lost. - */ - public void onLost(@NonNull Network network) {} - - /** - * Called if no network is found within the timeout time specified in - * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} call or if the - * requested network request cannot be fulfilled (whether or not a timeout was - * specified). When this callback is invoked the associated - * {@link NetworkRequest} will have already been removed and released, as if - * {@link #unregisterNetworkCallback(NetworkCallback)} had been called. - */ - public void onUnavailable() {} - - /** - * Called when the network corresponding to this request changes capabilities but still - * satisfies the requested criteria. - * - * <p>Starting with {@link android.os.Build.VERSION_CODES#O} this method is guaranteed - * to be called immediately after {@link #onAvailable}. - * - * <p>Do NOT call {@link #getLinkProperties(Network)} or other synchronous - * ConnectivityManager methods in this callback as this is prone to race conditions : - * calling these methods while in a callback may return an outdated or even a null object. - * - * @param network The {@link Network} whose capabilities have changed. - * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this - * network. - */ - public void onCapabilitiesChanged(@NonNull Network network, - @NonNull NetworkCapabilities networkCapabilities) {} - - /** - * Called when the network corresponding to this request changes {@link LinkProperties}. - * - * <p>Starting with {@link android.os.Build.VERSION_CODES#O} this method is guaranteed - * to be called immediately after {@link #onAvailable}. - * - * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or other synchronous - * ConnectivityManager methods in this callback as this is prone to race conditions : - * calling these methods while in a callback may return an outdated or even a null object. - * - * @param network The {@link Network} whose link properties have changed. - * @param linkProperties The new {@link LinkProperties} for this network. - */ - public void onLinkPropertiesChanged(@NonNull Network network, - @NonNull LinkProperties linkProperties) {} - - /** - * Called when the network the framework connected to for this request suspends data - * transmission temporarily. - * - * <p>This generally means that while the TCP connections are still live temporarily - * network data fails to transfer. To give a specific example, this is used on cellular - * networks to mask temporary outages when driving through a tunnel, etc. In general this - * means read operations on sockets on this network will block once the buffers are - * drained, and write operations will block once the buffers are full. - * - * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or - * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in - * this callback as this is prone to race conditions (there is no guarantee the objects - * returned by these methods will be current). - * - * @hide - */ - public void onNetworkSuspended(@NonNull Network network) {} - - /** - * Called when the network the framework connected to for this request - * returns from a {@link NetworkInfo.State#SUSPENDED} state. This should always be - * preceded by a matching {@link NetworkCallback#onNetworkSuspended} call. - - * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or - * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in - * this callback as this is prone to race conditions : calling these methods while in a - * callback may return an outdated or even a null object. - * - * @hide - */ - public void onNetworkResumed(@NonNull Network network) {} - - /** - * Called when access to the specified network is blocked or unblocked. - * - * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or - * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in - * this callback as this is prone to race conditions : calling these methods while in a - * callback may return an outdated or even a null object. - * - * @param network The {@link Network} whose blocked status has changed. - * @param blocked The blocked status of this {@link Network}. - */ - public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {} - - private NetworkRequest networkRequest; - } - - /** - * Constant error codes used by ConnectivityService to communicate about failures and errors - * across a Binder boundary. - * @hide - */ - public interface Errors { - int TOO_MANY_REQUESTS = 1; - } - - /** @hide */ - public static class TooManyRequestsException extends RuntimeException {} - - private static RuntimeException convertServiceException(ServiceSpecificException e) { - switch (e.errorCode) { - case Errors.TOO_MANY_REQUESTS: - return new TooManyRequestsException(); - default: - Log.w(TAG, "Unknown service error code " + e.errorCode); - return new RuntimeException(e); - } - } - - private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER; - /** @hide */ - public static final int CALLBACK_PRECHECK = BASE + 1; - /** @hide */ - public static final int CALLBACK_AVAILABLE = BASE + 2; - /** @hide arg1 = TTL */ - public static final int CALLBACK_LOSING = BASE + 3; - /** @hide */ - public static final int CALLBACK_LOST = BASE + 4; - /** @hide */ - public static final int CALLBACK_UNAVAIL = BASE + 5; - /** @hide */ - public static final int CALLBACK_CAP_CHANGED = BASE + 6; - /** @hide */ - public static final int CALLBACK_IP_CHANGED = BASE + 7; - /** @hide obj = NetworkCapabilities, arg1 = seq number */ - private static final int EXPIRE_LEGACY_REQUEST = BASE + 8; - /** @hide */ - public static final int CALLBACK_SUSPENDED = BASE + 9; - /** @hide */ - public static final int CALLBACK_RESUMED = BASE + 10; - /** @hide */ - public static final int CALLBACK_BLK_CHANGED = BASE + 11; - - /** @hide */ - public static String getCallbackName(int whichCallback) { - switch (whichCallback) { - case CALLBACK_PRECHECK: return "CALLBACK_PRECHECK"; - case CALLBACK_AVAILABLE: return "CALLBACK_AVAILABLE"; - case CALLBACK_LOSING: return "CALLBACK_LOSING"; - case CALLBACK_LOST: return "CALLBACK_LOST"; - case CALLBACK_UNAVAIL: return "CALLBACK_UNAVAIL"; - case CALLBACK_CAP_CHANGED: return "CALLBACK_CAP_CHANGED"; - case CALLBACK_IP_CHANGED: return "CALLBACK_IP_CHANGED"; - case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST"; - case CALLBACK_SUSPENDED: return "CALLBACK_SUSPENDED"; - case CALLBACK_RESUMED: return "CALLBACK_RESUMED"; - case CALLBACK_BLK_CHANGED: return "CALLBACK_BLK_CHANGED"; - default: - return Integer.toString(whichCallback); - } - } - - private class CallbackHandler extends Handler { - private static final String TAG = "ConnectivityManager.CallbackHandler"; - private static final boolean DBG = false; - - CallbackHandler(Looper looper) { - super(looper); - } - - CallbackHandler(Handler handler) { - this(Preconditions.checkNotNull(handler, "Handler cannot be null.").getLooper()); - } - - @Override - public void handleMessage(Message message) { - if (message.what == EXPIRE_LEGACY_REQUEST) { - expireRequest((NetworkCapabilities) message.obj, message.arg1); - return; - } - - final NetworkRequest request = getObject(message, NetworkRequest.class); - final Network network = getObject(message, Network.class); - final NetworkCallback callback; - synchronized (sCallbacks) { - callback = sCallbacks.get(request); - if (callback == null) { - Log.w(TAG, - "callback not found for " + getCallbackName(message.what) + " message"); - return; - } - if (message.what == CALLBACK_UNAVAIL) { - sCallbacks.remove(request); - callback.networkRequest = ALREADY_UNREGISTERED; - } - } - if (DBG) { - Log.d(TAG, getCallbackName(message.what) + " for network " + network); - } - - switch (message.what) { - case CALLBACK_PRECHECK: { - callback.onPreCheck(network); - break; - } - case CALLBACK_AVAILABLE: { - NetworkCapabilities cap = getObject(message, NetworkCapabilities.class); - LinkProperties lp = getObject(message, LinkProperties.class); - callback.onAvailable(network, cap, lp, message.arg1 != 0); - break; - } - case CALLBACK_LOSING: { - callback.onLosing(network, message.arg1); - break; - } - case CALLBACK_LOST: { - callback.onLost(network); - break; - } - case CALLBACK_UNAVAIL: { - callback.onUnavailable(); - break; - } - case CALLBACK_CAP_CHANGED: { - NetworkCapabilities cap = getObject(message, NetworkCapabilities.class); - callback.onCapabilitiesChanged(network, cap); - break; - } - case CALLBACK_IP_CHANGED: { - LinkProperties lp = getObject(message, LinkProperties.class); - callback.onLinkPropertiesChanged(network, lp); - break; - } - case CALLBACK_SUSPENDED: { - callback.onNetworkSuspended(network); - break; - } - case CALLBACK_RESUMED: { - callback.onNetworkResumed(network); - break; - } - case CALLBACK_BLK_CHANGED: { - boolean blocked = message.arg1 != 0; - callback.onBlockedStatusChanged(network, blocked); - } - } - } - - private <T> T getObject(Message msg, Class<T> c) { - return (T) msg.getData().getParcelable(c.getSimpleName()); - } - } - - private CallbackHandler getDefaultHandler() { - synchronized (sCallbacks) { - if (sCallbackHandler == null) { - sCallbackHandler = new CallbackHandler(ConnectivityThread.getInstanceLooper()); - } - return sCallbackHandler; - } - } - - private static final HashMap<NetworkRequest, NetworkCallback> sCallbacks = new HashMap<>(); - private static CallbackHandler sCallbackHandler; - - private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback, - int timeoutMs, NetworkRequest.Type reqType, int legacyType, CallbackHandler handler) { - printStackTrace(); - checkCallbackNotNull(callback); - Preconditions.checkArgument( - reqType == TRACK_DEFAULT || need != null, "null NetworkCapabilities"); - final NetworkRequest request; - final String callingPackageName = mContext.getOpPackageName(); - try { - synchronized(sCallbacks) { - if (callback.networkRequest != null - && callback.networkRequest != ALREADY_UNREGISTERED) { - // TODO: throw exception instead and enforce 1:1 mapping of callbacks - // and requests (http://b/20701525). - Log.e(TAG, "NetworkCallback was already registered"); - } - Messenger messenger = new Messenger(handler); - Binder binder = new Binder(); - if (reqType == LISTEN) { - request = mService.listenForNetwork( - need, messenger, binder, callingPackageName); - } else { - request = mService.requestNetwork( - need, reqType.ordinal(), messenger, timeoutMs, binder, legacyType, - callingPackageName, getAttributionTag()); - } - if (request != null) { - sCallbacks.put(request, callback); - } - callback.networkRequest = request; - } - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - throw convertServiceException(e); - } - return request; - } - - /** - * Helper function to request a network with a particular legacy type. - * - * This API is only for use in internal system code that requests networks with legacy type and - * relies on CONNECTIVITY_ACTION broadcasts instead of NetworkCallbacks. New caller should use - * {@link #requestNetwork(NetworkRequest, NetworkCallback, Handler)} instead. - * - * @param request {@link NetworkRequest} describing this request. - * @param timeoutMs The time in milliseconds to attempt looking for a suitable network - * before {@link NetworkCallback#onUnavailable()} is called. The timeout must - * be a positive value (i.e. >0). - * @param legacyType to specify the network type(#TYPE_*). - * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. - * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note - * the callback must not be shared - it uniquely specifies this request. - * - * @hide - */ - @SystemApi - @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) - public void requestNetwork(@NonNull NetworkRequest request, - int timeoutMs, int legacyType, @NonNull Handler handler, - @NonNull NetworkCallback networkCallback) { - if (legacyType == TYPE_NONE) { - throw new IllegalArgumentException("TYPE_NONE is meaningless legacy type"); - } - CallbackHandler cbHandler = new CallbackHandler(handler); - NetworkCapabilities nc = request.networkCapabilities; - sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, legacyType, cbHandler); - } - - /** - * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}. - * - * <p>This method will attempt to find the best network that matches the passed - * {@link NetworkRequest}, and to bring up one that does if none currently satisfies the - * criteria. The platform will evaluate which network is the best at its own discretion. - * Throughput, latency, cost per byte, policy, user preference and other considerations - * may be factored in the decision of what is considered the best network. - * - * <p>As long as this request is outstanding, the platform will try to maintain the best network - * matching this request, while always attempting to match the request to a better network if - * possible. If a better match is found, the platform will switch this request to the now-best - * network and inform the app of the newly best network by invoking - * {@link NetworkCallback#onAvailable(Network)} on the provided callback. Note that the platform - * will not try to maintain any other network than the best one currently matching the request: - * a network not matching any network request may be disconnected at any time. - * - * <p>For example, an application could use this method to obtain a connected cellular network - * even if the device currently has a data connection over Ethernet. This may cause the cellular - * radio to consume additional power. Or, an application could inform the system that it wants - * a network supporting sending MMSes and have the system let it know about the currently best - * MMS-supporting network through the provided {@link NetworkCallback}. - * - * <p>The status of the request can be followed by listening to the various callbacks described - * in {@link NetworkCallback}. The {@link Network} object passed to the callback methods can be - * used to direct traffic to the network (although accessing some networks may be subject to - * holding specific permissions). Callers will learn about the specific characteristics of the - * network through - * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)} and - * {@link NetworkCallback#onLinkPropertiesChanged(Network, LinkProperties)}. The methods of the - * provided {@link NetworkCallback} will only be invoked due to changes in the best network - * matching the request at any given time; therefore when a better network matching the request - * becomes available, the {@link NetworkCallback#onAvailable(Network)} method is called - * with the new network after which no further updates are given about the previously-best - * network, unless it becomes the best again at some later time. All callbacks are invoked - * in order on the same thread, which by default is a thread created by the framework running - * in the app. - * {@see #requestNetwork(NetworkRequest, NetworkCallback, Handler)} to change where the - * callbacks are invoked. - * - * <p>This{@link NetworkRequest} will live until released via - * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits, at - * which point the system may let go of the network at any time. - * - * <p>A version of this method which takes a timeout is - * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)}, that an app can use to only - * wait for a limited amount of time for the network to become unavailable. - * - * <p>It is presently unsupported to request a network with mutable - * {@link NetworkCapabilities} such as - * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or - * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL} - * as these {@code NetworkCapabilities} represent states that a particular - * network may never attain, and whether a network will attain these states - * is unknown prior to bringing up the network so the framework does not - * know how to go about satisfying a request with these capabilities. - * - * <p>This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.</p> - * - * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the - * number of outstanding requests to 100 per app (identified by their UID), shared with - * all variants of this method, of {@link #registerNetworkCallback} as well as - * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}. - * Requesting a network with this method will count toward this limit. If this limit is - * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources, - * make sure to unregister the callbacks with - * {@link #unregisterNetworkCallback(NetworkCallback)}. - * - * @param request {@link NetworkRequest} describing this request. - * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note - * the callback must not be shared - it uniquely specifies this request. - * The callback is invoked on the default internal Handler. - * @throws IllegalArgumentException if {@code request} contains invalid network capabilities. - * @throws SecurityException if missing the appropriate permissions. - * @throws RuntimeException if the app already has too many callbacks registered. - */ - public void requestNetwork(@NonNull NetworkRequest request, - @NonNull NetworkCallback networkCallback) { - requestNetwork(request, networkCallback, getDefaultHandler()); - } - - /** - * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}. - * - * This method behaves identically to {@link #requestNetwork(NetworkRequest, NetworkCallback)} - * but runs all the callbacks on the passed Handler. - * - * <p>This method has the same permission requirements as - * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, is subject to the same limitations, - * and throws the same exceptions in the same conditions. - * - * @param request {@link NetworkRequest} describing this request. - * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note - * the callback must not be shared - it uniquely specifies this request. - * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. - */ - public void requestNetwork(@NonNull NetworkRequest request, - @NonNull NetworkCallback networkCallback, @NonNull Handler handler) { - CallbackHandler cbHandler = new CallbackHandler(handler); - NetworkCapabilities nc = request.networkCapabilities; - sendRequestForNetwork(nc, networkCallback, 0, REQUEST, TYPE_NONE, cbHandler); - } - - /** - * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited - * by a timeout. - * - * This function behaves identically to the non-timed-out version - * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, but if a suitable network - * is not found within the given time (in milliseconds) the - * {@link NetworkCallback#onUnavailable()} callback is called. The request can still be - * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does - * not have to be released if timed-out (it is automatically released). Unregistering a - * request that timed out is not an error. - * - * <p>Do not use this method to poll for the existence of specific networks (e.g. with a small - * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided - * for that purpose. Calling this method will attempt to bring up the requested network. - * - * <p>This method has the same permission requirements as - * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, is subject to the same limitations, - * and throws the same exceptions in the same conditions. - * - * @param request {@link NetworkRequest} describing this request. - * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note - * the callback must not be shared - it uniquely specifies this request. - * @param timeoutMs The time in milliseconds to attempt looking for a suitable network - * before {@link NetworkCallback#onUnavailable()} is called. The timeout must - * be a positive value (i.e. >0). - */ - public void requestNetwork(@NonNull NetworkRequest request, - @NonNull NetworkCallback networkCallback, int timeoutMs) { - checkTimeout(timeoutMs); - NetworkCapabilities nc = request.networkCapabilities; - sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, TYPE_NONE, - getDefaultHandler()); - } - - /** - * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited - * by a timeout. - * - * This method behaves identically to - * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} but runs all the callbacks - * on the passed Handler. - * - * <p>This method has the same permission requirements as - * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, is subject to the same limitations, - * and throws the same exceptions in the same conditions. - * - * @param request {@link NetworkRequest} describing this request. - * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note - * the callback must not be shared - it uniquely specifies this request. - * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. - * @param timeoutMs The time in milliseconds to attempt looking for a suitable network - * before {@link NetworkCallback#onUnavailable} is called. - */ - public void requestNetwork(@NonNull NetworkRequest request, - @NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) { - checkTimeout(timeoutMs); - CallbackHandler cbHandler = new CallbackHandler(handler); - NetworkCapabilities nc = request.networkCapabilities; - sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, TYPE_NONE, cbHandler); - } - - /** - * The lookup key for a {@link Network} object included with the intent after - * successfully finding a network for the applications request. Retrieve it with - * {@link android.content.Intent#getParcelableExtra(String)}. - * <p> - * Note that if you intend to invoke {@link Network#openConnection(java.net.URL)} - * then you must get a ConnectivityManager instance before doing so. - */ - public static final String EXTRA_NETWORK = "android.net.extra.NETWORK"; - - /** - * The lookup key for a {@link NetworkRequest} object included with the intent after - * successfully finding a network for the applications request. Retrieve it with - * {@link android.content.Intent#getParcelableExtra(String)}. - */ - public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST"; - - - /** - * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}. - * - * This function behaves identically to the version that takes a NetworkCallback, but instead - * of {@link NetworkCallback} a {@link PendingIntent} is used. This means - * the request may outlive the calling application and get called back when a suitable - * network is found. - * <p> - * The operation is an Intent broadcast that goes to a broadcast receiver that - * you registered with {@link Context#registerReceiver} or through the - * <receiver> tag in an AndroidManifest.xml file - * <p> - * The operation Intent is delivered with two extras, a {@link Network} typed - * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest} - * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing - * the original requests parameters. It is important to create a new, - * {@link NetworkCallback} based request before completing the processing of the - * Intent to reserve the network or it will be released shortly after the Intent - * is processed. - * <p> - * If there is already a request for this Intent registered (with the equality of - * two Intents defined by {@link Intent#filterEquals}), then it will be removed and - * replaced by this one, effectively releasing the previous {@link NetworkRequest}. - * <p> - * The request may be released normally by calling - * {@link #releaseNetworkRequest(android.app.PendingIntent)}. - * <p>It is presently unsupported to request a network with either - * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or - * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL} - * as these {@code NetworkCapabilities} represent states that a particular - * network may never attain, and whether a network will attain these states - * is unknown prior to bringing up the network so the framework does not - * know how to go about satisfying a request with these capabilities. - * - * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the - * number of outstanding requests to 100 per app (identified by their UID), shared with - * all variants of this method, of {@link #registerNetworkCallback} as well as - * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}. - * Requesting a network with this method will count toward this limit. If this limit is - * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources, - * make sure to unregister the callbacks with {@link #unregisterNetworkCallback(PendingIntent)} - * or {@link #releaseNetworkRequest(PendingIntent)}. - * - * <p>This method requires the caller to hold either the - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission - * or the ability to modify system settings as determined by - * {@link android.provider.Settings.System#canWrite}.</p> - * - * @param request {@link NetworkRequest} describing this request. - * @param operation Action to perform when the network is available (corresponds - * to the {@link NetworkCallback#onAvailable} call. Typically - * comes from {@link PendingIntent#getBroadcast}. Cannot be null. - * @throws IllegalArgumentException if {@code request} contains invalid network capabilities. - * @throws SecurityException if missing the appropriate permissions. - * @throws RuntimeException if the app already has too many callbacks registered. - */ - public void requestNetwork(@NonNull NetworkRequest request, - @NonNull PendingIntent operation) { - printStackTrace(); - checkPendingIntentNotNull(operation); - try { - mService.pendingRequestForNetwork( - request.networkCapabilities, operation, mContext.getOpPackageName(), - getAttributionTag()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - throw convertServiceException(e); - } - } - - /** - * Removes a request made via {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)} - * <p> - * This method has the same behavior as - * {@link #unregisterNetworkCallback(android.app.PendingIntent)} with respect to - * releasing network resources and disconnecting. - * - * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the - * PendingIntent passed to - * {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)} with the - * corresponding NetworkRequest you'd like to remove. Cannot be null. - */ - public void releaseNetworkRequest(@NonNull PendingIntent operation) { - printStackTrace(); - checkPendingIntentNotNull(operation); - try { - mService.releasePendingNetworkRequest(operation); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - private static void checkPendingIntentNotNull(PendingIntent intent) { - Preconditions.checkNotNull(intent, "PendingIntent cannot be null."); - } - - private static void checkCallbackNotNull(NetworkCallback callback) { - Preconditions.checkNotNull(callback, "null NetworkCallback"); - } - - private static void checkTimeout(int timeoutMs) { - Preconditions.checkArgumentPositive(timeoutMs, "timeoutMs must be strictly positive."); - } - - /** - * Registers to receive notifications about all networks which satisfy the given - * {@link NetworkRequest}. The callbacks will continue to be called until - * either the application exits or {@link #unregisterNetworkCallback(NetworkCallback)} is - * called. - * - * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the - * number of outstanding requests to 100 per app (identified by their UID), shared with - * all variants of this method, of {@link #requestNetwork} as well as - * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}. - * Requesting a network with this method will count toward this limit. If this limit is - * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources, - * make sure to unregister the callbacks with - * {@link #unregisterNetworkCallback(NetworkCallback)}. - * - * @param request {@link NetworkRequest} describing this request. - * @param networkCallback The {@link NetworkCallback} that the system will call as suitable - * networks change state. - * The callback is invoked on the default internal Handler. - * @throws RuntimeException if the app already has too many callbacks registered. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public void registerNetworkCallback(@NonNull NetworkRequest request, - @NonNull NetworkCallback networkCallback) { - registerNetworkCallback(request, networkCallback, getDefaultHandler()); - } - - /** - * Registers to receive notifications about all networks which satisfy the given - * {@link NetworkRequest}. The callbacks will continue to be called until - * either the application exits or {@link #unregisterNetworkCallback(NetworkCallback)} is - * called. - * - * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the - * number of outstanding requests to 100 per app (identified by their UID), shared with - * all variants of this method, of {@link #requestNetwork} as well as - * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}. - * Requesting a network with this method will count toward this limit. If this limit is - * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources, - * make sure to unregister the callbacks with - * {@link #unregisterNetworkCallback(NetworkCallback)}. - * - * - * @param request {@link NetworkRequest} describing this request. - * @param networkCallback The {@link NetworkCallback} that the system will call as suitable - * networks change state. - * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. - * @throws RuntimeException if the app already has too many callbacks registered. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public void registerNetworkCallback(@NonNull NetworkRequest request, - @NonNull NetworkCallback networkCallback, @NonNull Handler handler) { - CallbackHandler cbHandler = new CallbackHandler(handler); - NetworkCapabilities nc = request.networkCapabilities; - sendRequestForNetwork(nc, networkCallback, 0, LISTEN, TYPE_NONE, cbHandler); - } - - /** - * Registers a PendingIntent to be sent when a network is available which satisfies the given - * {@link NetworkRequest}. - * - * This function behaves identically to the version that takes a NetworkCallback, but instead - * of {@link NetworkCallback} a {@link PendingIntent} is used. This means - * the request may outlive the calling application and get called back when a suitable - * network is found. - * <p> - * The operation is an Intent broadcast that goes to a broadcast receiver that - * you registered with {@link Context#registerReceiver} or through the - * <receiver> tag in an AndroidManifest.xml file - * <p> - * The operation Intent is delivered with two extras, a {@link Network} typed - * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest} - * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing - * the original requests parameters. - * <p> - * If there is already a request for this Intent registered (with the equality of - * two Intents defined by {@link Intent#filterEquals}), then it will be removed and - * replaced by this one, effectively releasing the previous {@link NetworkRequest}. - * <p> - * The request may be released normally by calling - * {@link #unregisterNetworkCallback(android.app.PendingIntent)}. - * - * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the - * number of outstanding requests to 100 per app (identified by their UID), shared with - * all variants of this method, of {@link #requestNetwork} as well as - * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}. - * Requesting a network with this method will count toward this limit. If this limit is - * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources, - * make sure to unregister the callbacks with {@link #unregisterNetworkCallback(PendingIntent)} - * or {@link #releaseNetworkRequest(PendingIntent)}. - * - * @param request {@link NetworkRequest} describing this request. - * @param operation Action to perform when the network is available (corresponds - * to the {@link NetworkCallback#onAvailable} call. Typically - * comes from {@link PendingIntent#getBroadcast}. Cannot be null. - * @throws RuntimeException if the app already has too many callbacks registered. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public void registerNetworkCallback(@NonNull NetworkRequest request, - @NonNull PendingIntent operation) { - printStackTrace(); - checkPendingIntentNotNull(operation); - try { - mService.pendingListenForNetwork( - request.networkCapabilities, operation, mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (ServiceSpecificException e) { - throw convertServiceException(e); - } - } - - /** - * Registers to receive notifications about changes in the system default network. The callbacks - * will continue to be called until either the application exits or - * {@link #unregisterNetworkCallback(NetworkCallback)} is called. - * - * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the - * number of outstanding requests to 100 per app (identified by their UID), shared with - * all variants of this method, of {@link #requestNetwork} as well as - * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}. - * Requesting a network with this method will count toward this limit. If this limit is - * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources, - * make sure to unregister the callbacks with - * {@link #unregisterNetworkCallback(NetworkCallback)}. - * - * @param networkCallback The {@link NetworkCallback} that the system will call as the - * system default network changes. - * The callback is invoked on the default internal Handler. - * @throws RuntimeException if the app already has too many callbacks registered. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback) { - registerDefaultNetworkCallback(networkCallback, getDefaultHandler()); - } - - /** - * Registers to receive notifications about changes in the system default network. The callbacks - * will continue to be called until either the application exits or - * {@link #unregisterNetworkCallback(NetworkCallback)} is called. - * - * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the - * number of outstanding requests to 100 per app (identified by their UID), shared with - * all variants of this method, of {@link #requestNetwork} as well as - * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}. - * Requesting a network with this method will count toward this limit. If this limit is - * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources, - * make sure to unregister the callbacks with - * {@link #unregisterNetworkCallback(NetworkCallback)}. - * - * @param networkCallback The {@link NetworkCallback} that the system will call as the - * system default network changes. - * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. - * @throws RuntimeException if the app already has too many callbacks registered. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback, - @NonNull Handler handler) { - // This works because if the NetworkCapabilities are null, - // ConnectivityService takes them from the default request. - // - // Since the capabilities are exactly the same as the default request's - // capabilities, this request is guaranteed, at all times, to be - // satisfied by the same network, if any, that satisfies the default - // request, i.e., the system default network. - CallbackHandler cbHandler = new CallbackHandler(handler); - sendRequestForNetwork(null /* NetworkCapabilities need */, networkCallback, 0, - TRACK_DEFAULT, TYPE_NONE, cbHandler); - } - - /** - * Requests bandwidth update for a given {@link Network} and returns whether the update request - * is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying - * network connection for updated bandwidth information. The caller will be notified via - * {@link ConnectivityManager.NetworkCallback} if there is an update. Notice that this - * method assumes that the caller has previously called - * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} to listen for network - * changes. - * - * @param network {@link Network} specifying which network you're interested. - * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid. - */ - public boolean requestBandwidthUpdate(@NonNull Network network) { - try { - return mService.requestBandwidthUpdate(network); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Unregisters a {@code NetworkCallback} and possibly releases networks originating from - * {@link #requestNetwork(NetworkRequest, NetworkCallback)} and - * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} calls. - * If the given {@code NetworkCallback} had previously been used with - * {@code #requestNetwork}, any networks that had been connected to only to satisfy that request - * will be disconnected. - * - * Notifications that would have triggered that {@code NetworkCallback} will immediately stop - * triggering it as soon as this call returns. - * - * @param networkCallback The {@link NetworkCallback} used when making the request. - */ - public void unregisterNetworkCallback(@NonNull NetworkCallback networkCallback) { - printStackTrace(); - checkCallbackNotNull(networkCallback); - final List<NetworkRequest> reqs = new ArrayList<>(); - // Find all requests associated to this callback and stop callback triggers immediately. - // Callback is reusable immediately. http://b/20701525, http://b/35921499. - synchronized (sCallbacks) { - Preconditions.checkArgument(networkCallback.networkRequest != null, - "NetworkCallback was not registered"); - if (networkCallback.networkRequest == ALREADY_UNREGISTERED) { - Log.d(TAG, "NetworkCallback was already unregistered"); - return; - } - for (Map.Entry<NetworkRequest, NetworkCallback> e : sCallbacks.entrySet()) { - if (e.getValue() == networkCallback) { - reqs.add(e.getKey()); - } - } - // TODO: throw exception if callback was registered more than once (http://b/20701525). - for (NetworkRequest r : reqs) { - try { - mService.releaseNetworkRequest(r); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - // Only remove mapping if rpc was successful. - sCallbacks.remove(r); - } - networkCallback.networkRequest = ALREADY_UNREGISTERED; - } - } - - /** - * Unregisters a callback previously registered via - * {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}. - * - * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the - * PendingIntent passed to - * {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}. - * Cannot be null. - */ - public void unregisterNetworkCallback(@NonNull PendingIntent operation) { - releaseNetworkRequest(operation); - } - - /** - * Informs the system whether it should switch to {@code network} regardless of whether it is - * validated or not. If {@code accept} is true, and the network was explicitly selected by the - * user (e.g., by selecting a Wi-Fi network in the Settings app), then the network will become - * the system default network regardless of any other network that's currently connected. If - * {@code always} is true, then the choice is remembered, so that the next time the user - * connects to this network, the system will switch to it. - * - * @param network The network to accept. - * @param accept Whether to accept the network even if unvalidated. - * @param always Whether to remember this choice in the future. - * - * @hide - */ - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void setAcceptUnvalidated(Network network, boolean accept, boolean always) { - try { - mService.setAcceptUnvalidated(network, accept, always); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Informs the system whether it should consider the network as validated even if it only has - * partial connectivity. If {@code accept} is true, then the network will be considered as - * validated even if connectivity is only partial. If {@code always} is true, then the choice - * is remembered, so that the next time the user connects to this network, the system will - * switch to it. - * - * @param network The network to accept. - * @param accept Whether to consider the network as validated even if it has partial - * connectivity. - * @param always Whether to remember this choice in the future. - * - * @hide - */ - @RequiresPermission(android.Manifest.permission.NETWORK_STACK) - public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) { - try { - mService.setAcceptPartialConnectivity(network, accept, always); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Informs the system to penalize {@code network}'s score when it becomes unvalidated. This is - * only meaningful if the system is configured not to penalize such networks, e.g., if the - * {@code config_networkAvoidBadWifi} configuration variable is set to 0 and the {@code - * NETWORK_AVOID_BAD_WIFI setting is unset}. - * - * @param network The network to accept. - * - * @hide - */ - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void setAvoidUnvalidated(Network network) { - try { - mService.setAvoidUnvalidated(network); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Requests that the system open the captive portal app on the specified network. - * - * @param network The network to log into. - * - * @hide - */ - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void startCaptivePortalApp(Network network) { - try { - mService.startCaptivePortalApp(network); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Requests that the system open the captive portal app with the specified extras. - * - * <p>This endpoint is exclusively for use by the NetworkStack and is protected by the - * corresponding permission. - * @param network Network on which the captive portal was detected. - * @param appExtras Extras to include in the app start intent. - * @hide - */ - @SystemApi - @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) - public void startCaptivePortalApp(@NonNull Network network, @NonNull Bundle appExtras) { - try { - mService.startCaptivePortalAppInternal(network, appExtras); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Determine whether the device is configured to avoid bad wifi. - * @hide - */ - @SystemApi - @RequiresPermission(anyOf = { - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_STACK}) - public boolean shouldAvoidBadWifi() { - try { - return mService.shouldAvoidBadWifi(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * It is acceptable to briefly use multipath data to provide seamless connectivity for - * time-sensitive user-facing operations when the system default network is temporarily - * unresponsive. The amount of data should be limited (less than one megabyte for every call to - * this method), and the operation should be infrequent to ensure that data usage is limited. - * - * An example of such an operation might be a time-sensitive foreground activity, such as a - * voice command, that the user is performing while walking out of range of a Wi-Fi network. - */ - public static final int MULTIPATH_PREFERENCE_HANDOVER = 1 << 0; - - /** - * It is acceptable to use small amounts of multipath data on an ongoing basis to provide - * a backup channel for traffic that is primarily going over another network. - * - * An example might be maintaining backup connections to peers or servers for the purpose of - * fast fallback if the default network is temporarily unresponsive or disconnects. The traffic - * on backup paths should be negligible compared to the traffic on the main path. - */ - public static final int MULTIPATH_PREFERENCE_RELIABILITY = 1 << 1; - - /** - * It is acceptable to use metered data to improve network latency and performance. - */ - public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 1 << 2; - - /** - * Return value to use for unmetered networks. On such networks we currently set all the flags - * to true. - * @hide - */ - public static final int MULTIPATH_PREFERENCE_UNMETERED = - MULTIPATH_PREFERENCE_HANDOVER | - MULTIPATH_PREFERENCE_RELIABILITY | - MULTIPATH_PREFERENCE_PERFORMANCE; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(flag = true, value = { - MULTIPATH_PREFERENCE_HANDOVER, - MULTIPATH_PREFERENCE_RELIABILITY, - MULTIPATH_PREFERENCE_PERFORMANCE, - }) - public @interface MultipathPreference { - } - - /** - * Provides a hint to the calling application on whether it is desirable to use the - * multinetwork APIs (e.g., {@link Network#openConnection}, {@link Network#bindSocket}, etc.) - * for multipath data transfer on this network when it is not the system default network. - * Applications desiring to use multipath network protocols should call this method before - * each such operation. - * - * @param network The network on which the application desires to use multipath data. - * If {@code null}, this method will return the a preference that will generally - * apply to metered networks. - * @return a bitwise OR of zero or more of the {@code MULTIPATH_PREFERENCE_*} constants. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - public @MultipathPreference int getMultipathPreference(@Nullable Network network) { - try { - return mService.getMultipathPreference(network); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Resets all connectivity manager settings back to factory defaults. - * @hide - */ - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void factoryReset() { - try { - mService.factoryReset(); - mTetheringManager.stopAllTethering(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Binds the current process to {@code network}. All Sockets created in the future - * (and not explicitly bound via a bound SocketFactory from - * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to - * {@code network}. All host name resolutions will be limited to {@code network} as well. - * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to - * work and all host name resolutions will fail. This is by design so an application doesn't - * accidentally use Sockets it thinks are still bound to a particular {@link Network}. - * To clear binding pass {@code null} for {@code network}. Using individually bound - * Sockets created by Network.getSocketFactory().createSocket() and - * performing network-specific host name resolutions via - * {@link Network#getAllByName Network.getAllByName} is preferred to calling - * {@code bindProcessToNetwork}. - * - * @param network The {@link Network} to bind the current process to, or {@code null} to clear - * the current binding. - * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid. - */ - public boolean bindProcessToNetwork(@Nullable Network network) { - // Forcing callers to call through non-static function ensures ConnectivityManager - // instantiated. - return setProcessDefaultNetwork(network); - } - - /** - * Binds the current process to {@code network}. All Sockets created in the future - * (and not explicitly bound via a bound SocketFactory from - * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to - * {@code network}. All host name resolutions will be limited to {@code network} as well. - * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to - * work and all host name resolutions will fail. This is by design so an application doesn't - * accidentally use Sockets it thinks are still bound to a particular {@link Network}. - * To clear binding pass {@code null} for {@code network}. Using individually bound - * Sockets created by Network.getSocketFactory().createSocket() and - * performing network-specific host name resolutions via - * {@link Network#getAllByName Network.getAllByName} is preferred to calling - * {@code setProcessDefaultNetwork}. - * - * @param network The {@link Network} to bind the current process to, or {@code null} to clear - * the current binding. - * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid. - * @deprecated This function can throw {@link IllegalStateException}. Use - * {@link #bindProcessToNetwork} instead. {@code bindProcessToNetwork} - * is a direct replacement. - */ - @Deprecated - public static boolean setProcessDefaultNetwork(@Nullable Network network) { - int netId = (network == null) ? NETID_UNSET : network.netId; - boolean isSameNetId = (netId == NetworkUtils.getBoundNetworkForProcess()); - - if (netId != NETID_UNSET) { - netId = network.getNetIdForResolv(); - } - - if (!NetworkUtils.bindProcessToNetwork(netId)) { - return false; - } - - if (!isSameNetId) { - // Set HTTP proxy system properties to match network. - // TODO: Deprecate this static method and replace it with a non-static version. - try { - Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy()); - } catch (SecurityException e) { - // The process doesn't have ACCESS_NETWORK_STATE, so we can't fetch the proxy. - Log.e(TAG, "Can't set proxy properties", e); - } - // Must flush DNS cache as new network may have different DNS resolutions. - InetAddress.clearDnsCache(); - // Must flush socket pool as idle sockets will be bound to previous network and may - // cause subsequent fetches to be performed on old network. - NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged(); - } - - return true; - } - - /** - * Returns the {@link Network} currently bound to this process via - * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound. - * - * @return {@code Network} to which this process is bound, or {@code null}. - */ - @Nullable - public Network getBoundNetworkForProcess() { - // Forcing callers to call thru non-static function ensures ConnectivityManager - // instantiated. - return getProcessDefaultNetwork(); - } - - /** - * Returns the {@link Network} currently bound to this process via - * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound. - * - * @return {@code Network} to which this process is bound, or {@code null}. - * @deprecated Using this function can lead to other functions throwing - * {@link IllegalStateException}. Use {@link #getBoundNetworkForProcess} instead. - * {@code getBoundNetworkForProcess} is a direct replacement. - */ - @Deprecated - @Nullable - public static Network getProcessDefaultNetwork() { - int netId = NetworkUtils.getBoundNetworkForProcess(); - if (netId == NETID_UNSET) return null; - return new Network(netId); - } - - private void unsupportedStartingFrom(int version) { - if (Process.myUid() == Process.SYSTEM_UID) { - // The getApplicationInfo() call we make below is not supported in system context. Let - // the call through here, and rely on the fact that ConnectivityService will refuse to - // allow the system to use these APIs anyway. - return; - } - - if (mContext.getApplicationInfo().targetSdkVersion >= version) { - throw new UnsupportedOperationException( - "This method is not supported in target SDK version " + version + " and above"); - } - } - - // Checks whether the calling app can use the legacy routing API (startUsingNetworkFeature, - // stopUsingNetworkFeature, requestRouteToHost), and if not throw UnsupportedOperationException. - // TODO: convert the existing system users (Tethering, GnssLocationProvider) to the new APIs and - // remove these exemptions. Note that this check is not secure, and apps can still access these - // functions by accessing ConnectivityService directly. However, it should be clear that doing - // so is unsupported and may break in the future. http://b/22728205 - private void checkLegacyRoutingApiAccess() { - unsupportedStartingFrom(VERSION_CODES.M); - } - - /** - * Binds host resolutions performed by this process to {@code network}. - * {@link #bindProcessToNetwork} takes precedence over this setting. - * - * @param network The {@link Network} to bind host resolutions from the current process to, or - * {@code null} to clear the current binding. - * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid. - * @hide - * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}. - */ - @Deprecated - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static boolean setProcessDefaultNetworkForHostResolution(Network network) { - return NetworkUtils.bindProcessToNetworkForHostResolution( - (network == null) ? NETID_UNSET : network.getNetIdForResolv()); - } - - /** - * Device is not restricting metered network activity while application is running on - * background. - */ - public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; - - /** - * Device is restricting metered network activity while application is running on background, - * but application is allowed to bypass it. - * <p> - * In this state, application should take action to mitigate metered network access. - * For example, a music streaming application should switch to a low-bandwidth bitrate. - */ - public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; - - /** - * Device is restricting metered network activity while application is running on background. - * <p> - * In this state, application should not try to use the network while running on background, - * because it would be denied. - */ - public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; - - /** - * A change in the background metered network activity restriction has occurred. - * <p> - * Applications should call {@link #getRestrictBackgroundStatus()} to check if the restriction - * applies to them. - * <p> - * This is only sent to registered receivers, not manifest receivers. - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_RESTRICT_BACKGROUND_CHANGED = - "android.net.conn.RESTRICT_BACKGROUND_CHANGED"; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(flag = false, value = { - RESTRICT_BACKGROUND_STATUS_DISABLED, - RESTRICT_BACKGROUND_STATUS_WHITELISTED, - RESTRICT_BACKGROUND_STATUS_ENABLED, - }) - public @interface RestrictBackgroundStatus { - } - - private INetworkPolicyManager getNetworkPolicyManager() { - synchronized (this) { - if (mNPManager != null) { - return mNPManager; - } - mNPManager = INetworkPolicyManager.Stub.asInterface(ServiceManager - .getService(Context.NETWORK_POLICY_SERVICE)); - return mNPManager; - } - } - - /** - * Determines if the calling application is subject to metered network restrictions while - * running on background. - * - * @return {@link #RESTRICT_BACKGROUND_STATUS_DISABLED}, - * {@link #RESTRICT_BACKGROUND_STATUS_ENABLED}, - * or {@link #RESTRICT_BACKGROUND_STATUS_WHITELISTED} - */ - public @RestrictBackgroundStatus int getRestrictBackgroundStatus() { - try { - return getNetworkPolicyManager().getRestrictBackgroundByCaller(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * The network watchlist is a list of domains and IP addresses that are associated with - * potentially harmful apps. This method returns the SHA-256 of the watchlist config file - * currently used by the system for validation purposes. - * - * @return Hash of network watchlist config file. Null if config does not exist. - */ - @Nullable - public byte[] getNetworkWatchlistConfigHash() { - try { - return mService.getNetworkWatchlistConfigHash(); - } catch (RemoteException e) { - Log.e(TAG, "Unable to get watchlist config hash"); - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns the {@code uid} of the owner of a network connection. - * - * @param protocol The protocol of the connection. Only {@code IPPROTO_TCP} and {@code - * IPPROTO_UDP} currently supported. - * @param local The local {@link InetSocketAddress} of a connection. - * @param remote The remote {@link InetSocketAddress} of a connection. - * @return {@code uid} if the connection is found and the app has permission to observe it - * (e.g., if it is associated with the calling VPN app's VpnService tunnel) or {@link - * android.os.Process#INVALID_UID} if the connection is not found. - * @throws {@link SecurityException} if the caller is not the active VpnService for the current - * user. - * @throws {@link IllegalArgumentException} if an unsupported protocol is requested. - */ - public int getConnectionOwnerUid( - int protocol, @NonNull InetSocketAddress local, @NonNull InetSocketAddress remote) { - ConnectionInfo connectionInfo = new ConnectionInfo(protocol, local, remote); - try { - return mService.getConnectionOwnerUid(connectionInfo); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - private void printStackTrace() { - if (DEBUG) { - final StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); - final StringBuffer sb = new StringBuffer(); - for (int i = 3; i < callStack.length; i++) { - final String stackTrace = callStack[i].toString(); - if (stackTrace == null || stackTrace.contains("android.os")) { - break; - } - sb.append(" [").append(stackTrace).append("]"); - } - Log.d(TAG, "StackLog:" + sb.toString()); - } - } - - /** - * Simulates a Data Stall for the specified Network. - * - * <p>This method should only be used for tests. - * - * <p>The caller must be the owner of the specified Network. - * - * @param detectionMethod The detection method used to identify the Data Stall. - * @param timestampMillis The timestamp at which the stall 'occurred', in milliseconds. - * @param network The Network for which a Data Stall is being simluated. - * @param extras The PersistableBundle of extras included in the Data Stall notification. - * @throws SecurityException if the caller is not the owner of the given network. - * @hide - */ - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_TEST_NETWORKS, - android.Manifest.permission.NETWORK_STACK}) - public void simulateDataStall(int detectionMethod, long timestampMillis, - @NonNull Network network, @NonNull PersistableBundle extras) { - try { - mService.simulateDataStall(detectionMethod, timestampMillis, network, extras); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - } - - private void setOemNetworkPreference(@NonNull OemNetworkPreferences preference) { - Log.d(TAG, "setOemNetworkPreference called with preference: " - + preference.toString()); - } - - @NonNull - private final List<QosCallbackConnection> mQosCallbackConnections = new ArrayList<>(); - - /** - * Registers a {@link QosSocketInfo} with an associated {@link QosCallback}. The callback will - * receive available QoS events related to the {@link Network} and local ip + port - * specified within socketInfo. - * <p/> - * The same {@link QosCallback} must be unregistered before being registered a second time, - * otherwise {@link QosCallbackRegistrationException} is thrown. - * <p/> - * This API does not, in itself, require any permission if called with a network that is not - * restricted. However, the underlying implementation currently only supports the IMS network, - * which is always restricted. That means non-preinstalled callers can't possibly find this API - * useful, because they'd never be called back on networks that they would have access to. - * - * @throws SecurityException if {@link QosSocketInfo#getNetwork()} is restricted and the app is - * missing CONNECTIVITY_USE_RESTRICTED_NETWORKS permission. - * @throws QosCallback.QosCallbackRegistrationException if qosCallback is already registered. - * @throws RuntimeException if the app already has too many callbacks registered. - * - * Exceptions after the time of registration is passed through - * {@link QosCallback#onError(QosCallbackException)}. see: {@link QosCallbackException}. - * - * @param socketInfo the socket information used to match QoS events - * @param callback receives qos events that satisfy socketInfo - * @param executor The executor on which the callback will be invoked. The provided - * {@link Executor} must run callback sequentially, otherwise the order of - * callbacks cannot be guaranteed. - * - * @hide - */ - @SystemApi - public void registerQosCallback(@NonNull final QosSocketInfo socketInfo, - @NonNull final QosCallback callback, - @CallbackExecutor @NonNull final Executor executor) { - Objects.requireNonNull(socketInfo, "socketInfo must be non-null"); - Objects.requireNonNull(callback, "callback must be non-null"); - Objects.requireNonNull(executor, "executor must be non-null"); - - try { - synchronized (mQosCallbackConnections) { - if (getQosCallbackConnection(callback) == null) { - final QosCallbackConnection connection = - new QosCallbackConnection(this, callback, executor); - mQosCallbackConnections.add(connection); - mService.registerQosSocketCallback(socketInfo, connection); - } else { - Log.e(TAG, "registerQosCallback: Callback already registered"); - throw new QosCallbackRegistrationException(); - } - } - } catch (final RemoteException e) { - Log.e(TAG, "registerQosCallback: Error while registering ", e); - - // The same unregister method method is called for consistency even though nothing - // will be sent to the ConnectivityService since the callback was never successfully - // registered. - unregisterQosCallback(callback); - e.rethrowFromSystemServer(); - } catch (final ServiceSpecificException e) { - Log.e(TAG, "registerQosCallback: Error while registering ", e); - unregisterQosCallback(callback); - throw convertServiceException(e); - } - } - - /** - * Unregisters the given {@link QosCallback}. The {@link QosCallback} will no longer receive - * events once unregistered and can be registered a second time. - * <p/> - * If the {@link QosCallback} does not have an active registration, it is a no-op. - * - * @param callback the callback being unregistered - * - * @hide - */ - @SystemApi - public void unregisterQosCallback(@NonNull final QosCallback callback) { - Objects.requireNonNull(callback, "The callback must be non-null"); - try { - synchronized (mQosCallbackConnections) { - final QosCallbackConnection connection = getQosCallbackConnection(callback); - if (connection != null) { - connection.stopReceivingMessages(); - mService.unregisterQosCallback(connection); - mQosCallbackConnections.remove(connection); - } else { - Log.d(TAG, "unregisterQosCallback: Callback not registered"); - } - } - } catch (final RemoteException e) { - Log.e(TAG, "unregisterQosCallback: Error while unregistering ", e); - e.rethrowFromSystemServer(); - } - } - - /** - * Gets the connection related to the callback. - * - * @param callback the callback to look up - * @return the related connection - */ - @Nullable - private QosCallbackConnection getQosCallbackConnection(final QosCallback callback) { - for (final QosCallbackConnection connection : mQosCallbackConnections) { - // Checking by reference here is intentional - if (connection.getCallback() == callback) { - return connection; - } - } - return null; - } - - /** - * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, but - * does not cause any networks to retain the NET_CAPABILITY_FOREGROUND capability. This can - * be used to request that the system provide a network without causing the network to be - * in the foreground. - * - * <p>This method will attempt to find the best network that matches the passed - * {@link NetworkRequest}, and to bring up one that does if none currently satisfies the - * criteria. The platform will evaluate which network is the best at its own discretion. - * Throughput, latency, cost per byte, policy, user preference and other considerations - * may be factored in the decision of what is considered the best network. - * - * <p>As long as this request is outstanding, the platform will try to maintain the best network - * matching this request, while always attempting to match the request to a better network if - * possible. If a better match is found, the platform will switch this request to the now-best - * network and inform the app of the newly best network by invoking - * {@link NetworkCallback#onAvailable(Network)} on the provided callback. Note that the platform - * will not try to maintain any other network than the best one currently matching the request: - * a network not matching any network request may be disconnected at any time. - * - * <p>For example, an application could use this method to obtain a connected cellular network - * even if the device currently has a data connection over Ethernet. This may cause the cellular - * radio to consume additional power. Or, an application could inform the system that it wants - * a network supporting sending MMSes and have the system let it know about the currently best - * MMS-supporting network through the provided {@link NetworkCallback}. - * - * <p>The status of the request can be followed by listening to the various callbacks described - * in {@link NetworkCallback}. The {@link Network} object passed to the callback methods can be - * used to direct traffic to the network (although accessing some networks may be subject to - * holding specific permissions). Callers will learn about the specific characteristics of the - * network through - * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)} and - * {@link NetworkCallback#onLinkPropertiesChanged(Network, LinkProperties)}. The methods of the - * provided {@link NetworkCallback} will only be invoked due to changes in the best network - * matching the request at any given time; therefore when a better network matching the request - * becomes available, the {@link NetworkCallback#onAvailable(Network)} method is called - * with the new network after which no further updates are given about the previously-best - * network, unless it becomes the best again at some later time. All callbacks are invoked - * in order on the same thread, which by default is a thread created by the framework running - * in the app. - * - * <p>This{@link NetworkRequest} will live until released via - * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits, at - * which point the system may let go of the network at any time. - * - * <p>It is presently unsupported to request a network with mutable - * {@link NetworkCapabilities} such as - * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or - * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL} - * as these {@code NetworkCapabilities} represent states that a particular - * network may never attain, and whether a network will attain these states - * is unknown prior to bringing up the network so the framework does not - * know how to go about satisfying a request with these capabilities. - * - * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the - * number of outstanding requests to 100 per app (identified by their UID), shared with - * all variants of this method, of {@link #registerNetworkCallback} as well as - * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}. - * Requesting a network with this method will count toward this limit. If this limit is - * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources, - * make sure to unregister the callbacks with - * {@link #unregisterNetworkCallback(NetworkCallback)}. - * - * @param request {@link NetworkRequest} describing this request. - * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. - * If null, the callback is invoked on the default internal Handler. - * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note - * the callback must not be shared - it uniquely specifies this request. - * @throws IllegalArgumentException if {@code request} contains invalid network capabilities. - * @throws SecurityException if missing the appropriate permissions. - * @throws RuntimeException if the app already has too many callbacks registered. - * - * @hide - */ - @SystemApi(client = MODULE_LIBRARIES) - @SuppressLint("ExecutorRegistration") - @RequiresPermission(anyOf = { - android.Manifest.permission.NETWORK_SETTINGS, - android.Manifest.permission.NETWORK_STACK, - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK - }) - public void requestBackgroundNetwork(@NonNull NetworkRequest request, - @Nullable Handler handler, @NonNull NetworkCallback networkCallback) { - final NetworkCapabilities nc = request.networkCapabilities; - sendRequestForNetwork(nc, networkCallback, 0, BACKGROUND_REQUEST, - TYPE_NONE, handler == null ? getDefaultHandler() : new CallbackHandler(handler)); - } -} diff --git a/core/java/android/net/ConnectivityMetricsEvent.aidl b/core/java/android/net/ConnectivityMetricsEvent.aidl deleted file mode 100644 index 1c541dc4c8cc..000000000000 --- a/core/java/android/net/ConnectivityMetricsEvent.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -/** {@hide} */ -parcelable ConnectivityMetricsEvent; diff --git a/core/java/android/net/ConnectivityThread.java b/core/java/android/net/ConnectivityThread.java deleted file mode 100644 index 0b218e738b77..000000000000 --- a/core/java/android/net/ConnectivityThread.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.os.HandlerThread; -import android.os.Looper; - -/** - * Shared singleton connectivity thread for the system. This is a thread for - * connectivity operations such as AsyncChannel connections to system services. - * Various connectivity manager objects can use this singleton as a common - * resource for their handlers instead of creating separate threads of their own. - * @hide - */ -public final class ConnectivityThread extends HandlerThread { - - // A class implementing the lazy holder idiom: the unique static instance - // of ConnectivityThread is instantiated in a thread-safe way (guaranteed by - // the language specs) the first time that Singleton is referenced in get() - // or getInstanceLooper(). - private static class Singleton { - private static final ConnectivityThread INSTANCE = createInstance(); - } - - private ConnectivityThread() { - super("ConnectivityThread"); - } - - private static ConnectivityThread createInstance() { - ConnectivityThread t = new ConnectivityThread(); - t.start(); - return t; - } - - public static ConnectivityThread get() { - return Singleton.INSTANCE; - } - - public static Looper getInstanceLooper() { - return Singleton.INSTANCE.getLooper(); - } -} diff --git a/core/java/android/net/DhcpInfo.aidl b/core/java/android/net/DhcpInfo.aidl deleted file mode 100644 index 29cd21fe7652..000000000000 --- a/core/java/android/net/DhcpInfo.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -parcelable DhcpInfo; diff --git a/core/java/android/net/DhcpInfo.java b/core/java/android/net/DhcpInfo.java deleted file mode 100644 index 912df67a0b45..000000000000 --- a/core/java/android/net/DhcpInfo.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * A simple object for retrieving the results of a DHCP request. - */ -public class DhcpInfo implements Parcelable { - public int ipAddress; - public int gateway; - public int netmask; - public int dns1; - public int dns2; - public int serverAddress; - - public int leaseDuration; - - public DhcpInfo() { - super(); - } - - /** copy constructor {@hide} */ - public DhcpInfo(DhcpInfo source) { - if (source != null) { - ipAddress = source.ipAddress; - gateway = source.gateway; - netmask = source.netmask; - dns1 = source.dns1; - dns2 = source.dns2; - serverAddress = source.serverAddress; - leaseDuration = source.leaseDuration; - } - } - - public String toString() { - StringBuffer str = new StringBuffer(); - - str.append("ipaddr "); putAddress(str, ipAddress); - str.append(" gateway "); putAddress(str, gateway); - str.append(" netmask "); putAddress(str, netmask); - str.append(" dns1 "); putAddress(str, dns1); - str.append(" dns2 "); putAddress(str, dns2); - str.append(" DHCP server "); putAddress(str, serverAddress); - str.append(" lease ").append(leaseDuration).append(" seconds"); - - return str.toString(); - } - - private static void putAddress(StringBuffer buf, int addr) { - buf.append(NetworkUtils.intToInetAddress(addr).getHostAddress()); - } - - /** Implement the Parcelable interface */ - public int describeContents() { - return 0; - } - - /** Implement the Parcelable interface */ - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(ipAddress); - dest.writeInt(gateway); - dest.writeInt(netmask); - dest.writeInt(dns1); - dest.writeInt(dns2); - dest.writeInt(serverAddress); - dest.writeInt(leaseDuration); - } - - /** Implement the Parcelable interface */ - public static final @android.annotation.NonNull Creator<DhcpInfo> CREATOR = - new Creator<DhcpInfo>() { - public DhcpInfo createFromParcel(Parcel in) { - DhcpInfo info = new DhcpInfo(); - info.ipAddress = in.readInt(); - info.gateway = in.readInt(); - info.netmask = in.readInt(); - info.dns1 = in.readInt(); - info.dns2 = in.readInt(); - info.serverAddress = in.readInt(); - info.leaseDuration = in.readInt(); - return info; - } - - public DhcpInfo[] newArray(int size) { - return new DhcpInfo[size]; - } - }; -} diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java deleted file mode 100644 index 3f7660f5709a..000000000000 --- a/core/java/android/net/DnsResolver.java +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.NetworkUtils.getDnsNetwork; -import static android.net.NetworkUtils.resNetworkCancel; -import static android.net.NetworkUtils.resNetworkQuery; -import static android.net.NetworkUtils.resNetworkResult; -import static android.net.NetworkUtils.resNetworkSend; -import static android.net.util.DnsUtils.haveIpv4; -import static android.net.util.DnsUtils.haveIpv6; -import static android.net.util.DnsUtils.rfc6724Sort; -import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR; -import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; -import static android.system.OsConstants.ENONET; - -import android.annotation.CallbackExecutor; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.os.CancellationSignal; -import android.os.Looper; -import android.os.MessageQueue; -import android.system.ErrnoException; -import android.util.Log; - -import com.android.net.module.util.DnsPacket; - -import java.io.FileDescriptor; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executor; - -/** - * Dns resolver class for asynchronous dns querying - * - * Note that if a client sends a query with more than 1 record in the question section but - * the remote dns server does not support this, it may not respond at all, leading to a timeout. - * - */ -public final class DnsResolver { - private static final String TAG = "DnsResolver"; - private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR; - private static final int MAXPACKET = 8 * 1024; - private static final int SLEEP_TIME_MS = 2; - - @IntDef(prefix = { "CLASS_" }, value = { - CLASS_IN - }) - @Retention(RetentionPolicy.SOURCE) - @interface QueryClass {} - public static final int CLASS_IN = 1; - - @IntDef(prefix = { "TYPE_" }, value = { - TYPE_A, - TYPE_AAAA - }) - @Retention(RetentionPolicy.SOURCE) - @interface QueryType {} - public static final int TYPE_A = 1; - public static final int TYPE_AAAA = 28; - - @IntDef(prefix = { "FLAG_" }, value = { - FLAG_EMPTY, - FLAG_NO_RETRY, - FLAG_NO_CACHE_STORE, - FLAG_NO_CACHE_LOOKUP - }) - @Retention(RetentionPolicy.SOURCE) - @interface QueryFlag {} - public static final int FLAG_EMPTY = 0; - public static final int FLAG_NO_RETRY = 1 << 0; - public static final int FLAG_NO_CACHE_STORE = 1 << 1; - public static final int FLAG_NO_CACHE_LOOKUP = 1 << 2; - - @IntDef(prefix = { "ERROR_" }, value = { - ERROR_PARSE, - ERROR_SYSTEM - }) - @Retention(RetentionPolicy.SOURCE) - @interface DnsError {} - /** - * Indicates that there was an error parsing the response the query. - * The cause of this error is available via getCause() and is a {@link ParseException}. - */ - public static final int ERROR_PARSE = 0; - /** - * Indicates that there was an error sending the query. - * The cause of this error is available via getCause() and is an ErrnoException. - */ - public static final int ERROR_SYSTEM = 1; - - private static final int NETID_UNSET = 0; - - private static final DnsResolver sInstance = new DnsResolver(); - - /** - * Get instance for DnsResolver - */ - public static @NonNull DnsResolver getInstance() { - return sInstance; - } - - private DnsResolver() {} - - /** - * Base interface for answer callbacks - * - * @param <T> The type of the answer - */ - public interface Callback<T> { - /** - * Success response to - * {@link android.net.DnsResolver#query query()} or - * {@link android.net.DnsResolver#rawQuery rawQuery()}. - * - * Invoked when the answer to a query was successfully parsed. - * - * @param answer <T> answer to the query. - * @param rcode The response code in the DNS response. - * - * {@see android.net.DnsResolver#query query()} - */ - void onAnswer(@NonNull T answer, int rcode); - /** - * Error response to - * {@link android.net.DnsResolver#query query()} or - * {@link android.net.DnsResolver#rawQuery rawQuery()}. - * - * Invoked when there is no valid answer to - * {@link android.net.DnsResolver#query query()} - * {@link android.net.DnsResolver#rawQuery rawQuery()}. - * - * @param error a {@link DnsException} object with additional - * detail regarding the failure - */ - void onError(@NonNull DnsException error); - } - - /** - * Class to represent DNS error - */ - public static class DnsException extends Exception { - /** - * DNS error code as one of the ERROR_* constants - */ - @DnsError public final int code; - - DnsException(@DnsError int code, @Nullable Throwable cause) { - super(cause); - this.code = code; - } - } - - /** - * Send a raw DNS query. - * The answer will be provided asynchronously through the provided {@link Callback}. - * - * @param network {@link Network} specifying which network to query on. - * {@code null} for query on default network. - * @param query blob message to query - * @param flags flags as a combination of the FLAGS_* constants - * @param executor The {@link Executor} that the callback should be executed on. - * @param cancellationSignal used by the caller to signal if the query should be - * cancelled. May be {@code null}. - * @param callback a {@link Callback} which will be called to notify the caller - * of the result of dns query. - */ - public void rawQuery(@Nullable Network network, @NonNull byte[] query, @QueryFlag int flags, - @NonNull @CallbackExecutor Executor executor, - @Nullable CancellationSignal cancellationSignal, - @NonNull Callback<? super byte[]> callback) { - if (cancellationSignal != null && cancellationSignal.isCanceled()) { - return; - } - final Object lock = new Object(); - final FileDescriptor queryfd; - try { - queryfd = resNetworkSend((network != null) - ? network.getNetIdForResolv() : NETID_UNSET, query, query.length, flags); - } catch (ErrnoException e) { - executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e))); - return; - } - - synchronized (lock) { - registerFDListener(executor, queryfd, callback, cancellationSignal, lock); - if (cancellationSignal == null) return; - addCancellationSignal(cancellationSignal, queryfd, lock); - } - } - - /** - * Send a DNS query with the specified name, class and query type. - * The answer will be provided asynchronously through the provided {@link Callback}. - * - * @param network {@link Network} specifying which network to query on. - * {@code null} for query on default network. - * @param domain domain name to query - * @param nsClass dns class as one of the CLASS_* constants - * @param nsType dns resource record (RR) type as one of the TYPE_* constants - * @param flags flags as a combination of the FLAGS_* constants - * @param executor The {@link Executor} that the callback should be executed on. - * @param cancellationSignal used by the caller to signal if the query should be - * cancelled. May be {@code null}. - * @param callback a {@link Callback} which will be called to notify the caller - * of the result of dns query. - */ - public void rawQuery(@Nullable Network network, @NonNull String domain, - @QueryClass int nsClass, @QueryType int nsType, @QueryFlag int flags, - @NonNull @CallbackExecutor Executor executor, - @Nullable CancellationSignal cancellationSignal, - @NonNull Callback<? super byte[]> callback) { - if (cancellationSignal != null && cancellationSignal.isCanceled()) { - return; - } - final Object lock = new Object(); - final FileDescriptor queryfd; - try { - queryfd = resNetworkQuery((network != null) - ? network.getNetIdForResolv() : NETID_UNSET, domain, nsClass, nsType, flags); - } catch (ErrnoException e) { - executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e))); - return; - } - synchronized (lock) { - registerFDListener(executor, queryfd, callback, cancellationSignal, lock); - if (cancellationSignal == null) return; - addCancellationSignal(cancellationSignal, queryfd, lock); - } - } - - private class InetAddressAnswerAccumulator implements Callback<byte[]> { - private final List<InetAddress> mAllAnswers; - private final Network mNetwork; - private int mRcode; - private DnsException mDnsException; - private final Callback<? super List<InetAddress>> mUserCallback; - private final int mTargetAnswerCount; - private int mReceivedAnswerCount = 0; - - InetAddressAnswerAccumulator(@NonNull Network network, int size, - @NonNull Callback<? super List<InetAddress>> callback) { - mNetwork = network; - mTargetAnswerCount = size; - mAllAnswers = new ArrayList<>(); - mUserCallback = callback; - } - - private boolean maybeReportError() { - if (mRcode != 0) { - mUserCallback.onAnswer(mAllAnswers, mRcode); - return true; - } - if (mDnsException != null) { - mUserCallback.onError(mDnsException); - return true; - } - return false; - } - - private void maybeReportAnswer() { - if (++mReceivedAnswerCount != mTargetAnswerCount) return; - if (mAllAnswers.isEmpty() && maybeReportError()) return; - mUserCallback.onAnswer(rfc6724Sort(mNetwork, mAllAnswers), mRcode); - } - - @Override - public void onAnswer(@NonNull byte[] answer, int rcode) { - // If at least one query succeeded, return an rcode of 0. - // Otherwise, arbitrarily return the first rcode received. - if (mReceivedAnswerCount == 0 || rcode == 0) { - mRcode = rcode; - } - try { - mAllAnswers.addAll(new DnsAddressAnswer(answer).getAddresses()); - } catch (DnsPacket.ParseException e) { - // Convert the com.android.net.module.util.DnsPacket.ParseException to an - // android.net.ParseException. This is the type that was used in Q and is implied - // by the public documentation of ERROR_PARSE. - // - // DnsPacket cannot throw android.net.ParseException directly because it's @hide. - ParseException pe = new ParseException(e.reason, e.getCause()); - pe.setStackTrace(e.getStackTrace()); - mDnsException = new DnsException(ERROR_PARSE, pe); - } - maybeReportAnswer(); - } - - @Override - public void onError(@NonNull DnsException error) { - mDnsException = error; - maybeReportAnswer(); - } - } - - /** - * Send a DNS query with the specified name on a network with both IPv4 and IPv6, - * get back a set of InetAddresses with rfc6724 sorting style asynchronously. - * - * This method will examine the connection ability on given network, and query IPv4 - * and IPv6 if connection is available. - * - * If at least one query succeeded with valid answer, rcode will be 0 - * - * The answer will be provided asynchronously through the provided {@link Callback}. - * - * @param network {@link Network} specifying which network to query on. - * {@code null} for query on default network. - * @param domain domain name to query - * @param flags flags as a combination of the FLAGS_* constants - * @param executor The {@link Executor} that the callback should be executed on. - * @param cancellationSignal used by the caller to signal if the query should be - * cancelled. May be {@code null}. - * @param callback a {@link Callback} which will be called to notify the - * caller of the result of dns query. - */ - public void query(@Nullable Network network, @NonNull String domain, @QueryFlag int flags, - @NonNull @CallbackExecutor Executor executor, - @Nullable CancellationSignal cancellationSignal, - @NonNull Callback<? super List<InetAddress>> callback) { - if (cancellationSignal != null && cancellationSignal.isCanceled()) { - return; - } - final Object lock = new Object(); - final Network queryNetwork; - try { - queryNetwork = (network != null) ? network : getDnsNetwork(); - } catch (ErrnoException e) { - executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e))); - return; - } - final boolean queryIpv6 = haveIpv6(queryNetwork); - final boolean queryIpv4 = haveIpv4(queryNetwork); - - // This can only happen if queryIpv4 and queryIpv6 are both false. - // This almost certainly means that queryNetwork does not exist or no longer exists. - if (!queryIpv6 && !queryIpv4) { - executor.execute(() -> callback.onError( - new DnsException(ERROR_SYSTEM, new ErrnoException("resNetworkQuery", ENONET)))); - return; - } - - final FileDescriptor v4fd; - final FileDescriptor v6fd; - - int queryCount = 0; - - if (queryIpv6) { - try { - v6fd = resNetworkQuery(queryNetwork.getNetIdForResolv(), domain, CLASS_IN, - TYPE_AAAA, flags); - } catch (ErrnoException e) { - executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e))); - return; - } - queryCount++; - } else v6fd = null; - - // Avoiding gateways drop packets if queries are sent too close together - try { - Thread.sleep(SLEEP_TIME_MS); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - - if (queryIpv4) { - try { - v4fd = resNetworkQuery(queryNetwork.getNetIdForResolv(), domain, CLASS_IN, TYPE_A, - flags); - } catch (ErrnoException e) { - if (queryIpv6) resNetworkCancel(v6fd); // Closes fd, marks it invalid. - executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e))); - return; - } - queryCount++; - } else v4fd = null; - - final InetAddressAnswerAccumulator accumulator = - new InetAddressAnswerAccumulator(queryNetwork, queryCount, callback); - - synchronized (lock) { - if (queryIpv6) { - registerFDListener(executor, v6fd, accumulator, cancellationSignal, lock); - } - if (queryIpv4) { - registerFDListener(executor, v4fd, accumulator, cancellationSignal, lock); - } - if (cancellationSignal == null) return; - cancellationSignal.setOnCancelListener(() -> { - synchronized (lock) { - if (queryIpv4) cancelQuery(v4fd); - if (queryIpv6) cancelQuery(v6fd); - } - }); - } - } - - /** - * Send a DNS query with the specified name and query type, get back a set of - * InetAddresses with rfc6724 sorting style asynchronously. - * - * The answer will be provided asynchronously through the provided {@link Callback}. - * - * @param network {@link Network} specifying which network to query on. - * {@code null} for query on default network. - * @param domain domain name to query - * @param nsType dns resource record (RR) type as one of the TYPE_* constants - * @param flags flags as a combination of the FLAGS_* constants - * @param executor The {@link Executor} that the callback should be executed on. - * @param cancellationSignal used by the caller to signal if the query should be - * cancelled. May be {@code null}. - * @param callback a {@link Callback} which will be called to notify the caller - * of the result of dns query. - */ - public void query(@Nullable Network network, @NonNull String domain, - @QueryType int nsType, @QueryFlag int flags, - @NonNull @CallbackExecutor Executor executor, - @Nullable CancellationSignal cancellationSignal, - @NonNull Callback<? super List<InetAddress>> callback) { - if (cancellationSignal != null && cancellationSignal.isCanceled()) { - return; - } - final Object lock = new Object(); - final FileDescriptor queryfd; - final Network queryNetwork; - try { - queryNetwork = (network != null) ? network : getDnsNetwork(); - queryfd = resNetworkQuery(queryNetwork.getNetIdForResolv(), domain, CLASS_IN, nsType, - flags); - } catch (ErrnoException e) { - executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e))); - return; - } - final InetAddressAnswerAccumulator accumulator = - new InetAddressAnswerAccumulator(queryNetwork, 1, callback); - synchronized (lock) { - registerFDListener(executor, queryfd, accumulator, cancellationSignal, lock); - if (cancellationSignal == null) return; - addCancellationSignal(cancellationSignal, queryfd, lock); - } - } - - /** - * Class to retrieve DNS response - * - * @hide - */ - public static final class DnsResponse { - public final @NonNull byte[] answerbuf; - public final int rcode; - public DnsResponse(@NonNull byte[] answerbuf, int rcode) { - this.answerbuf = answerbuf; - this.rcode = rcode; - } - } - - private void registerFDListener(@NonNull Executor executor, - @NonNull FileDescriptor queryfd, @NonNull Callback<? super byte[]> answerCallback, - @Nullable CancellationSignal cancellationSignal, @NonNull Object lock) { - final MessageQueue mainThreadMessageQueue = Looper.getMainLooper().getQueue(); - mainThreadMessageQueue.addOnFileDescriptorEventListener( - queryfd, - FD_EVENTS, - (fd, events) -> { - // b/134310704 - // Unregister fd event listener before resNetworkResult is called to prevent - // race condition caused by fd reused. - // For example when querying v4 and v6, it's possible that the first query ends - // and the fd is closed before the second request starts, which might return - // the same fd for the second request. By that time, the looper must have - // unregistered the fd, otherwise another event listener can't be registered. - mainThreadMessageQueue.removeOnFileDescriptorEventListener(fd); - - executor.execute(() -> { - DnsResponse resp = null; - ErrnoException exception = null; - synchronized (lock) { - if (cancellationSignal != null && cancellationSignal.isCanceled()) { - return; - } - try { - resp = resNetworkResult(fd); // Closes fd, marks it invalid. - } catch (ErrnoException e) { - Log.e(TAG, "resNetworkResult:" + e.toString()); - exception = e; - } - } - if (exception != null) { - answerCallback.onError(new DnsException(ERROR_SYSTEM, exception)); - return; - } - answerCallback.onAnswer(resp.answerbuf, resp.rcode); - }); - - // The file descriptor has already been unregistered, so it does not really - // matter what is returned here. In spirit 0 (meaning "unregister this FD") - // is still the closest to what the looper needs to do. When returning 0, - // Looper knows to ignore the fd if it has already been unregistered. - return 0; - }); - } - - private void cancelQuery(@NonNull FileDescriptor queryfd) { - if (!queryfd.valid()) return; - Looper.getMainLooper().getQueue().removeOnFileDescriptorEventListener(queryfd); - resNetworkCancel(queryfd); // Closes fd, marks it invalid. - } - - private void addCancellationSignal(@NonNull CancellationSignal cancellationSignal, - @NonNull FileDescriptor queryfd, @NonNull Object lock) { - cancellationSignal.setOnCancelListener(() -> { - synchronized (lock) { - cancelQuery(queryfd); - } - }); - } - - private static class DnsAddressAnswer extends DnsPacket { - private static final String TAG = "DnsResolver.DnsAddressAnswer"; - private static final boolean DBG = false; - - private final int mQueryType; - - DnsAddressAnswer(@NonNull byte[] data) throws ParseException { - super(data); - if ((mHeader.flags & (1 << 15)) == 0) { - throw new ParseException("Not an answer packet"); - } - if (mHeader.getRecordCount(QDSECTION) == 0) { - throw new ParseException("No question found"); - } - // Expect only one question in question section. - mQueryType = mRecords[QDSECTION].get(0).nsType; - } - - public @NonNull List<InetAddress> getAddresses() { - final List<InetAddress> results = new ArrayList<InetAddress>(); - if (mHeader.getRecordCount(ANSECTION) == 0) return results; - - for (final DnsRecord ansSec : mRecords[ANSECTION]) { - // Only support A and AAAA, also ignore answers if query type != answer type. - int nsType = ansSec.nsType; - if (nsType != mQueryType || (nsType != TYPE_A && nsType != TYPE_AAAA)) { - continue; - } - try { - results.add(InetAddress.getByAddress(ansSec.getRR())); - } catch (UnknownHostException e) { - if (DBG) { - Log.w(TAG, "rr to address fail"); - } - } - } - return results; - } - } - -} diff --git a/core/java/android/net/ICaptivePortal.aidl b/core/java/android/net/ICaptivePortal.aidl deleted file mode 100644 index fe21905c7002..000000000000 --- a/core/java/android/net/ICaptivePortal.aidl +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2015, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -/** - * Interface to inform NetworkMonitor of decisions of app handling captive portal. - * @hide - */ -oneway interface ICaptivePortal { - void appRequest(int request); - void appResponse(int response); - void logEvent(int eventId, String packageName); -} diff --git a/core/java/android/net/IConnectivityDiagnosticsCallback.aidl b/core/java/android/net/IConnectivityDiagnosticsCallback.aidl deleted file mode 100644 index 82b64a928000..000000000000 --- a/core/java/android/net/IConnectivityDiagnosticsCallback.aidl +++ /dev/null @@ -1,28 +0,0 @@ -/** - * - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.net.ConnectivityDiagnosticsManager; -import android.net.Network; - -/** @hide */ -oneway interface IConnectivityDiagnosticsCallback { - void onConnectivityReportAvailable(in ConnectivityDiagnosticsManager.ConnectivityReport report); - void onDataStallSuspected(in ConnectivityDiagnosticsManager.DataStallReport report); - void onNetworkConnectivityReported(in Network n, boolean hasConnectivity); -}
\ No newline at end of file diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl deleted file mode 100644 index 1b4d2e413943..000000000000 --- a/core/java/android/net/IConnectivityManager.aidl +++ /dev/null @@ -1,246 +0,0 @@ -/** - * Copyright (c) 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.app.PendingIntent; -import android.net.ConnectionInfo; -import android.net.ConnectivityDiagnosticsManager; -import android.net.IConnectivityDiagnosticsCallback; -import android.net.IQosCallback; -import android.net.ISocketKeepaliveCallback; -import android.net.LinkProperties; -import android.net.Network; -import android.net.NetworkAgentConfig; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.net.NetworkRequest; -import android.net.NetworkState; -import android.net.ProxyInfo; -import android.net.UidRange; -import android.net.QosSocketInfo; -import android.os.Bundle; -import android.os.IBinder; -import android.os.INetworkActivityListener; -import android.os.Messenger; -import android.os.ParcelFileDescriptor; -import android.os.PersistableBundle; -import android.os.ResultReceiver; - -import com.android.connectivity.aidl.INetworkAgent; -import com.android.internal.net.LegacyVpnInfo; -import com.android.internal.net.VpnConfig; -import com.android.internal.net.VpnProfile; - -/** - * Interface that answers queries about, and allows changing, the - * state of network connectivity. - */ -/** {@hide} */ -interface IConnectivityManager -{ - Network getActiveNetwork(); - Network getActiveNetworkForUid(int uid, boolean ignoreBlocked); - @UnsupportedAppUsage - NetworkInfo getActiveNetworkInfo(); - NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked); - @UnsupportedAppUsage(maxTargetSdk = 28) - NetworkInfo getNetworkInfo(int networkType); - NetworkInfo getNetworkInfoForUid(in Network network, int uid, boolean ignoreBlocked); - @UnsupportedAppUsage - NetworkInfo[] getAllNetworkInfo(); - Network getNetworkForType(int networkType); - Network[] getAllNetworks(); - NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser( - int userId, String callingPackageName); - - boolean isNetworkSupported(int networkType); - - @UnsupportedAppUsage - LinkProperties getActiveLinkProperties(); - LinkProperties getLinkPropertiesForType(int networkType); - LinkProperties getLinkProperties(in Network network); - - NetworkCapabilities getNetworkCapabilities(in Network network, String callingPackageName); - - @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) - NetworkState[] getAllNetworkState(); - - boolean isActiveNetworkMetered(); - - boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, - String callingPackageName, String callingAttributionTag); - - @UnsupportedAppUsage(maxTargetSdk = 29, - publicAlternatives = "Use {@code TetheringManager#getLastTetherError} as alternative") - int getLastTetherError(String iface); - - @UnsupportedAppUsage(maxTargetSdk = 29, - publicAlternatives = "Use {@code TetheringManager#getTetherableIfaces} as alternative") - String[] getTetherableIfaces(); - - @UnsupportedAppUsage(maxTargetSdk = 29, - publicAlternatives = "Use {@code TetheringManager#getTetheredIfaces} as alternative") - String[] getTetheredIfaces(); - - @UnsupportedAppUsage(maxTargetSdk = 29, - publicAlternatives = "Use {@code TetheringManager#getTetheringErroredIfaces} " - + "as Alternative") - String[] getTetheringErroredIfaces(); - - @UnsupportedAppUsage(maxTargetSdk = 29, - publicAlternatives = "Use {@code TetheringManager#getTetherableUsbRegexs} as alternative") - String[] getTetherableUsbRegexs(); - - @UnsupportedAppUsage(maxTargetSdk = 29, - publicAlternatives = "Use {@code TetheringManager#getTetherableWifiRegexs} as alternative") - String[] getTetherableWifiRegexs(); - - @UnsupportedAppUsage(maxTargetSdk = 28) - void reportInetCondition(int networkType, int percentage); - - void reportNetworkConnectivity(in Network network, boolean hasConnectivity); - - ProxyInfo getGlobalProxy(); - - void setGlobalProxy(in ProxyInfo p); - - ProxyInfo getProxyForNetwork(in Network nework); - - boolean prepareVpn(String oldPackage, String newPackage, int userId); - - void setVpnPackageAuthorization(String packageName, int userId, int vpnType); - - ParcelFileDescriptor establishVpn(in VpnConfig config); - - boolean provisionVpnProfile(in VpnProfile profile, String packageName); - - void deleteVpnProfile(String packageName); - - void startVpnProfile(String packageName); - - void stopVpnProfile(String packageName); - - VpnConfig getVpnConfig(int userId); - - @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) - void startLegacyVpn(in VpnProfile profile); - - LegacyVpnInfo getLegacyVpnInfo(int userId); - - boolean updateLockdownVpn(); - boolean isAlwaysOnVpnPackageSupported(int userId, String packageName); - boolean setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown, - in List<String> lockdownWhitelist); - String getAlwaysOnVpnPackage(int userId); - boolean isVpnLockdownEnabled(int userId); - List<String> getVpnLockdownWhitelist(int userId); - void setRequireVpnForUids(boolean requireVpn, in UidRange[] ranges); - - void setProvisioningNotificationVisible(boolean visible, int networkType, in String action); - - void setAirplaneMode(boolean enable); - - boolean requestBandwidthUpdate(in Network network); - - int registerNetworkFactory(in Messenger messenger, in String name); - void unregisterNetworkFactory(in Messenger messenger); - - int registerNetworkProvider(in Messenger messenger, in String name); - void unregisterNetworkProvider(in Messenger messenger); - - void declareNetworkRequestUnfulfillable(in NetworkRequest request); - - Network registerNetworkAgent(in INetworkAgent na, in NetworkInfo ni, in LinkProperties lp, - in NetworkCapabilities nc, int score, in NetworkAgentConfig config, - in int factorySerialNumber); - - NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, int reqType, - in Messenger messenger, int timeoutSec, in IBinder binder, int legacy, - String callingPackageName, String callingAttributionTag); - - NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities, - in PendingIntent operation, String callingPackageName, String callingAttributionTag); - - void releasePendingNetworkRequest(in PendingIntent operation); - - NetworkRequest listenForNetwork(in NetworkCapabilities networkCapabilities, - in Messenger messenger, in IBinder binder, String callingPackageName); - - void pendingListenForNetwork(in NetworkCapabilities networkCapabilities, - in PendingIntent operation, String callingPackageName); - - void releaseNetworkRequest(in NetworkRequest networkRequest); - - void setAcceptUnvalidated(in Network network, boolean accept, boolean always); - void setAcceptPartialConnectivity(in Network network, boolean accept, boolean always); - void setAvoidUnvalidated(in Network network); - void startCaptivePortalApp(in Network network); - void startCaptivePortalAppInternal(in Network network, in Bundle appExtras); - - boolean shouldAvoidBadWifi(); - int getMultipathPreference(in Network Network); - - NetworkRequest getDefaultRequest(); - - int getRestoreDefaultNetworkDelay(int networkType); - - boolean addVpnAddress(String address, int prefixLength); - boolean removeVpnAddress(String address, int prefixLength); - boolean setUnderlyingNetworksForVpn(in Network[] networks); - - void factoryReset(); - - void startNattKeepalive(in Network network, int intervalSeconds, - in ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr); - - void startNattKeepaliveWithFd(in Network network, in ParcelFileDescriptor pfd, int resourceId, - int intervalSeconds, in ISocketKeepaliveCallback cb, String srcAddr, - String dstAddr); - - void startTcpKeepalive(in Network network, in ParcelFileDescriptor pfd, int intervalSeconds, - in ISocketKeepaliveCallback cb); - - void stopKeepalive(in Network network, int slot); - - String getCaptivePortalServerUrl(); - - byte[] getNetworkWatchlistConfigHash(); - - int getConnectionOwnerUid(in ConnectionInfo connectionInfo); - boolean isCallerCurrentAlwaysOnVpnApp(); - boolean isCallerCurrentAlwaysOnVpnLockdownApp(); - - void registerConnectivityDiagnosticsCallback(in IConnectivityDiagnosticsCallback callback, - in NetworkRequest request, String callingPackageName); - void unregisterConnectivityDiagnosticsCallback(in IConnectivityDiagnosticsCallback callback); - - IBinder startOrGetTestNetworkService(); - - void simulateDataStall(int detectionMethod, long timestampMillis, in Network network, - in PersistableBundle extras); - - void systemReady(); - - void registerNetworkActivityListener(in INetworkActivityListener l); - - void unregisterNetworkActivityListener(in INetworkActivityListener l); - - boolean isDefaultNetworkActive(); - - void registerQosSocketCallback(in QosSocketInfo socketInfo, in IQosCallback callback); - void unregisterQosCallback(in IQosCallback callback); -} diff --git a/core/java/android/net/ISocketKeepaliveCallback.aidl b/core/java/android/net/ISocketKeepaliveCallback.aidl deleted file mode 100644 index 020fbcacbfef..000000000000 --- a/core/java/android/net/ISocketKeepaliveCallback.aidl +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -/** - * Callback to provide status changes of keepalive offload. - * - * @hide - */ -oneway interface ISocketKeepaliveCallback -{ - /** The keepalive was successfully started. */ - void onStarted(int slot); - /** The keepalive was successfully stopped. */ - void onStopped(); - /** The keepalive was stopped because of an error. */ - void onError(int error); - /** The keepalive on a TCP socket was stopped because the socket received data. */ - void onDataReceived(); -} diff --git a/core/java/android/net/ITestNetworkManager.aidl b/core/java/android/net/ITestNetworkManager.aidl deleted file mode 100644 index 2a863adde581..000000000000 --- a/core/java/android/net/ITestNetworkManager.aidl +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2018, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.net.LinkAddress; -import android.net.LinkProperties; -import android.net.TestNetworkInterface; -import android.os.IBinder; -import android.os.ParcelFileDescriptor; - -/** - * Interface that allows for creation and management of test-only networks. - * - * @hide - */ -interface ITestNetworkManager -{ - TestNetworkInterface createTunInterface(in LinkAddress[] linkAddrs); - TestNetworkInterface createTapInterface(); - - void setupTestNetwork(in String iface, in LinkProperties lp, in boolean isMetered, - in int[] administratorUids, in IBinder binder); - - void teardownTestNetwork(int netId); -} diff --git a/core/java/android/net/InetAddresses.java b/core/java/android/net/InetAddresses.java deleted file mode 100644 index 01b795e456fa..000000000000 --- a/core/java/android/net/InetAddresses.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; - -import libcore.net.InetAddressUtils; - -import java.net.InetAddress; - -/** - * Utility methods for {@link InetAddress} implementations. - */ -public class InetAddresses { - - private InetAddresses() {} - - /** - * Checks to see if the {@code address} is a numeric address (such as {@code "192.0.2.1"} or - * {@code "2001:db8::1:2"}). - * - * <p>A numeric address is either an IPv4 address containing exactly 4 decimal numbers or an - * IPv6 numeric address. IPv4 addresses that consist of either hexadecimal or octal digits or - * do not have exactly 4 numbers are not treated as numeric. - * - * <p>This method will never do a DNS lookup. - * - * @param address the address to parse. - * @return true if the supplied address is numeric, false otherwise. - */ - public static boolean isNumericAddress(@NonNull String address) { - return InetAddressUtils.isNumericAddress(address); - } - - /** - * Returns an InetAddress corresponding to the given numeric address (such - * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}). - * - * <p>See {@link #isNumericAddress(String)} (String)} for a definition as to what constitutes a - * numeric address. - * - * <p>This method will never do a DNS lookup. - * - * @param address the address to parse, must be numeric. - * @return an {@link InetAddress} instance corresponding to the address. - * @throws IllegalArgumentException if {@code address} is not a numeric address. - */ - public static @NonNull InetAddress parseNumericAddress(@NonNull String address) { - return InetAddressUtils.parseNumericAddress(address); - } -} diff --git a/core/java/android/net/InterfaceConfiguration.aidl b/core/java/android/net/InterfaceConfiguration.aidl deleted file mode 100644 index 8aa5e3452853..000000000000 --- a/core/java/android/net/InterfaceConfiguration.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -parcelable InterfaceConfiguration; diff --git a/core/java/android/net/InvalidPacketException.java b/core/java/android/net/InvalidPacketException.java deleted file mode 100644 index 1873d778c0f2..000000000000 --- a/core/java/android/net/InvalidPacketException.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.IntDef; -import android.annotation.SystemApi; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Thrown when a packet is invalid. - * @hide - */ -@SystemApi -public final class InvalidPacketException extends Exception { - private final int mError; - - // Must match SocketKeepalive#ERROR_INVALID_IP_ADDRESS. - /** Invalid IP address. */ - public static final int ERROR_INVALID_IP_ADDRESS = -21; - - // Must match SocketKeepalive#ERROR_INVALID_PORT. - /** Invalid port number. */ - public static final int ERROR_INVALID_PORT = -22; - - // Must match SocketKeepalive#ERROR_INVALID_LENGTH. - /** Invalid packet length. */ - public static final int ERROR_INVALID_LENGTH = -23; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "ERROR_" }, value = { - ERROR_INVALID_IP_ADDRESS, - ERROR_INVALID_PORT, - ERROR_INVALID_LENGTH - }) - public @interface ErrorCode {} - - /** - * This packet is invalid. - * See the error code for details. - */ - public InvalidPacketException(@ErrorCode final int error) { - this.mError = error; - } - - /** Get error code. */ - public int getError() { - return mError; - } -} diff --git a/core/java/android/net/IpConfiguration.aidl b/core/java/android/net/IpConfiguration.aidl deleted file mode 100644 index 7a30f0e79cad..000000000000 --- a/core/java/android/net/IpConfiguration.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -parcelable IpConfiguration; diff --git a/core/java/android/net/IpConfiguration.java b/core/java/android/net/IpConfiguration.java deleted file mode 100644 index 0b205642b321..000000000000 --- a/core/java/android/net/IpConfiguration.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SuppressLint; -import android.annotation.SystemApi; -import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Objects; - -/** - * A class representing a configured network. - * @hide - */ -@SystemApi -public final class IpConfiguration implements Parcelable { - private static final String TAG = "IpConfiguration"; - - // This enum has been used by apps through reflection for many releases. - // Therefore they can't just be removed. Duplicating these constants to - // give an alternate SystemApi is a worse option than exposing them. - @SuppressLint("Enum") - public enum IpAssignment { - /* Use statically configured IP settings. Configuration can be accessed - * with staticIpConfiguration */ - STATIC, - /* Use dynamically configured IP settings */ - DHCP, - /* no IP details are assigned, this is used to indicate - * that any existing IP settings should be retained */ - UNASSIGNED - } - - /** @hide */ - public IpAssignment ipAssignment; - - /** @hide */ - public StaticIpConfiguration staticIpConfiguration; - - // This enum has been used by apps through reflection for many releases. - // Therefore they can't just be removed. Duplicating these constants to - // give an alternate SystemApi is a worse option than exposing them. - @SuppressLint("Enum") - public enum ProxySettings { - /* No proxy is to be used. Any existing proxy settings - * should be cleared. */ - NONE, - /* Use statically configured proxy. Configuration can be accessed - * with httpProxy. */ - STATIC, - /* no proxy details are assigned, this is used to indicate - * that any existing proxy settings should be retained */ - UNASSIGNED, - /* Use a Pac based proxy. - */ - PAC - } - - /** @hide */ - public ProxySettings proxySettings; - - /** @hide */ - @UnsupportedAppUsage - public ProxyInfo httpProxy; - - private void init(IpAssignment ipAssignment, - ProxySettings proxySettings, - StaticIpConfiguration staticIpConfiguration, - ProxyInfo httpProxy) { - this.ipAssignment = ipAssignment; - this.proxySettings = proxySettings; - this.staticIpConfiguration = (staticIpConfiguration == null) ? - null : new StaticIpConfiguration(staticIpConfiguration); - this.httpProxy = (httpProxy == null) ? - null : new ProxyInfo(httpProxy); - } - - public IpConfiguration() { - init(IpAssignment.UNASSIGNED, ProxySettings.UNASSIGNED, null, null); - } - - /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public IpConfiguration(IpAssignment ipAssignment, - ProxySettings proxySettings, - StaticIpConfiguration staticIpConfiguration, - ProxyInfo httpProxy) { - init(ipAssignment, proxySettings, staticIpConfiguration, httpProxy); - } - - public IpConfiguration(@NonNull IpConfiguration source) { - this(); - if (source != null) { - init(source.ipAssignment, source.proxySettings, - source.staticIpConfiguration, source.httpProxy); - } - } - - public @NonNull IpAssignment getIpAssignment() { - return ipAssignment; - } - - public void setIpAssignment(@NonNull IpAssignment ipAssignment) { - this.ipAssignment = ipAssignment; - } - - public @Nullable StaticIpConfiguration getStaticIpConfiguration() { - return staticIpConfiguration; - } - - public void setStaticIpConfiguration(@Nullable StaticIpConfiguration staticIpConfiguration) { - this.staticIpConfiguration = staticIpConfiguration; - } - - public @NonNull ProxySettings getProxySettings() { - return proxySettings; - } - - public void setProxySettings(@NonNull ProxySettings proxySettings) { - this.proxySettings = proxySettings; - } - - public @Nullable ProxyInfo getHttpProxy() { - return httpProxy; - } - - public void setHttpProxy(@Nullable ProxyInfo httpProxy) { - this.httpProxy = httpProxy; - } - - @Override - public String toString() { - StringBuilder sbuf = new StringBuilder(); - sbuf.append("IP assignment: " + ipAssignment.toString()); - sbuf.append("\n"); - if (staticIpConfiguration != null) { - sbuf.append("Static configuration: " + staticIpConfiguration.toString()); - sbuf.append("\n"); - } - sbuf.append("Proxy settings: " + proxySettings.toString()); - sbuf.append("\n"); - if (httpProxy != null) { - sbuf.append("HTTP proxy: " + httpProxy.toString()); - sbuf.append("\n"); - } - - return sbuf.toString(); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - - if (!(o instanceof IpConfiguration)) { - return false; - } - - IpConfiguration other = (IpConfiguration) o; - return this.ipAssignment == other.ipAssignment && - this.proxySettings == other.proxySettings && - Objects.equals(this.staticIpConfiguration, other.staticIpConfiguration) && - Objects.equals(this.httpProxy, other.httpProxy); - } - - @Override - public int hashCode() { - return 13 + (staticIpConfiguration != null ? staticIpConfiguration.hashCode() : 0) + - 17 * ipAssignment.ordinal() + - 47 * proxySettings.ordinal() + - 83 * httpProxy.hashCode(); - } - - /** Implement the Parcelable interface */ - public int describeContents() { - return 0; - } - - /** Implement the Parcelable interface */ - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeString(ipAssignment.name()); - dest.writeString(proxySettings.name()); - dest.writeParcelable(staticIpConfiguration, flags); - dest.writeParcelable(httpProxy, flags); - } - - /** Implement the Parcelable interface */ - public static final @NonNull Creator<IpConfiguration> CREATOR = - new Creator<IpConfiguration>() { - public IpConfiguration createFromParcel(Parcel in) { - IpConfiguration config = new IpConfiguration(); - config.ipAssignment = IpAssignment.valueOf(in.readString()); - config.proxySettings = ProxySettings.valueOf(in.readString()); - config.staticIpConfiguration = in.readParcelable(null); - config.httpProxy = in.readParcelable(null); - return config; - } - - public IpConfiguration[] newArray(int size) { - return new IpConfiguration[size]; - } - }; -} diff --git a/core/java/android/net/IpPrefix.aidl b/core/java/android/net/IpPrefix.aidl deleted file mode 100644 index 0d70f2a1ed2c..000000000000 --- a/core/java/android/net/IpPrefix.aidl +++ /dev/null @@ -1,22 +0,0 @@ -/** - * - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -// @JavaOnlyStableParcelable only affects the parcelable when built as stable aidl (aidl_interface -// build rule). IpPrefix is also used in cpp but only as non-stable aidl. -@JavaOnlyStableParcelable parcelable IpPrefix cpp_header "binder/IpPrefix.h"; diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java deleted file mode 100644 index e7c801475c4d..000000000000 --- a/core/java/android/net/IpPrefix.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Pair; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Comparator; - -/** - * This class represents an IP prefix, i.e., a contiguous block of IP addresses aligned on a - * power of two boundary (also known as an "IP subnet"). A prefix is specified by two pieces of - * information: - * - * <ul> - * <li>A starting IP address (IPv4 or IPv6). This is the first IP address of the prefix. - * <li>A prefix length. This specifies the length of the prefix by specifing the number of bits - * in the IP address, starting from the most significant bit in network byte order, that - * are constant for all addresses in the prefix. - * </ul> - * - * For example, the prefix <code>192.0.2.0/24</code> covers the 256 IPv4 addresses from - * <code>192.0.2.0</code> to <code>192.0.2.255</code>, inclusive, and the prefix - * <code>2001:db8:1:2</code> covers the 2^64 IPv6 addresses from <code>2001:db8:1:2::</code> to - * <code>2001:db8:1:2:ffff:ffff:ffff:ffff</code>, inclusive. - * - * Objects of this class are immutable. - */ -public final class IpPrefix implements Parcelable { - private final byte[] address; // network byte order - private final int prefixLength; - - private void checkAndMaskAddressAndPrefixLength() { - if (address.length != 4 && address.length != 16) { - throw new IllegalArgumentException( - "IpPrefix has " + address.length + " bytes which is neither 4 nor 16"); - } - NetworkUtils.maskRawAddress(address, prefixLength); - } - - /** - * Constructs a new {@code IpPrefix} from a byte array containing an IPv4 or IPv6 address in - * network byte order and a prefix length. Silently truncates the address to the prefix length, - * so for example {@code 192.0.2.1/24} is silently converted to {@code 192.0.2.0/24}. - * - * @param address the IP address. Must be non-null and exactly 4 or 16 bytes long. - * @param prefixLength the prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6). - * - * @hide - */ - public IpPrefix(@NonNull byte[] address, @IntRange(from = 0, to = 128) int prefixLength) { - this.address = address.clone(); - this.prefixLength = prefixLength; - checkAndMaskAddressAndPrefixLength(); - } - - /** - * Constructs a new {@code IpPrefix} from an IPv4 or IPv6 address and a prefix length. Silently - * truncates the address to the prefix length, so for example {@code 192.0.2.1/24} is silently - * converted to {@code 192.0.2.0/24}. - * - * @param address the IP address. Must be non-null. - * @param prefixLength the prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6). - * @hide - */ - @SystemApi - public IpPrefix(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength) { - // We don't reuse the (byte[], int) constructor because it calls clone() on the byte array, - // which is unnecessary because getAddress() already returns a clone. - this.address = address.getAddress(); - this.prefixLength = prefixLength; - checkAndMaskAddressAndPrefixLength(); - } - - /** - * Constructs a new IpPrefix from a string such as "192.0.2.1/24" or "2001:db8::1/64". - * Silently truncates the address to the prefix length, so for example {@code 192.0.2.1/24} - * is silently converted to {@code 192.0.2.0/24}. - * - * @param prefix the prefix to parse - * - * @hide - */ - @SystemApi - public IpPrefix(@NonNull String prefix) { - // We don't reuse the (InetAddress, int) constructor because "error: call to this must be - // first statement in constructor". We could factor out setting the member variables to an - // init() method, but if we did, then we'd have to make the members non-final, or "error: - // cannot assign a value to final variable address". So we just duplicate the code here. - Pair<InetAddress, Integer> ipAndMask = NetworkUtils.parseIpAndMask(prefix); - this.address = ipAndMask.first.getAddress(); - this.prefixLength = ipAndMask.second; - checkAndMaskAddressAndPrefixLength(); - } - - /** - * Compares this {@code IpPrefix} object against the specified object in {@code obj}. Two - * objects are equal if they have the same startAddress and prefixLength. - * - * @param obj the object to be tested for equality. - * @return {@code true} if both objects are equal, {@code false} otherwise. - */ - @Override - public boolean equals(Object obj) { - if (!(obj instanceof IpPrefix)) { - return false; - } - IpPrefix that = (IpPrefix) obj; - return Arrays.equals(this.address, that.address) && this.prefixLength == that.prefixLength; - } - - /** - * Gets the hashcode of the represented IP prefix. - * - * @return the appropriate hashcode value. - */ - @Override - public int hashCode() { - return Arrays.hashCode(address) + 11 * prefixLength; - } - - /** - * Returns a copy of the first IP address in the prefix. Modifying the returned object does not - * change this object's contents. - * - * @return the address in the form of a byte array. - */ - public @NonNull InetAddress getAddress() { - try { - return InetAddress.getByAddress(address); - } catch (UnknownHostException e) { - // Cannot happen. InetAddress.getByAddress can only throw an exception if the byte - // array is the wrong length, but we check that in the constructor. - throw new IllegalArgumentException("Address is invalid"); - } - } - - /** - * Returns a copy of the IP address bytes in network order (the highest order byte is the zeroth - * element). Modifying the returned array does not change this object's contents. - * - * @return the address in the form of a byte array. - */ - public @NonNull byte[] getRawAddress() { - return address.clone(); - } - - /** - * Returns the prefix length of this {@code IpPrefix}. - * - * @return the prefix length. - */ - @IntRange(from = 0, to = 128) - public int getPrefixLength() { - return prefixLength; - } - - /** - * Determines whether the prefix contains the specified address. - * - * @param address An {@link InetAddress} to test. - * @return {@code true} if the prefix covers the given address. {@code false} otherwise. - */ - public boolean contains(@NonNull InetAddress address) { - byte[] addrBytes = address.getAddress(); - if (addrBytes == null || addrBytes.length != this.address.length) { - return false; - } - NetworkUtils.maskRawAddress(addrBytes, prefixLength); - return Arrays.equals(this.address, addrBytes); - } - - /** - * Returns whether the specified prefix is entirely contained in this prefix. - * - * Note this is mathematical inclusion, so a prefix is always contained within itself. - * @param otherPrefix the prefix to test - * @hide - */ - public boolean containsPrefix(@NonNull IpPrefix otherPrefix) { - if (otherPrefix.getPrefixLength() < prefixLength) return false; - final byte[] otherAddress = otherPrefix.getRawAddress(); - NetworkUtils.maskRawAddress(otherAddress, prefixLength); - return Arrays.equals(otherAddress, address); - } - - /** - * @hide - */ - public boolean isIPv6() { - return getAddress() instanceof Inet6Address; - } - - /** - * @hide - */ - public boolean isIPv4() { - return getAddress() instanceof Inet4Address; - } - - /** - * Returns a string representation of this {@code IpPrefix}. - * - * @return a string such as {@code "192.0.2.0/24"} or {@code "2001:db8:1:2::/64"}. - */ - public String toString() { - try { - return InetAddress.getByAddress(address).getHostAddress() + "/" + prefixLength; - } catch(UnknownHostException e) { - // Cosmic rays? - throw new IllegalStateException("IpPrefix with invalid address! Shouldn't happen.", e); - } - } - - /** - * Implement the Parcelable interface. - */ - public int describeContents() { - return 0; - } - - /** - * Implement the Parcelable interface. - */ - public void writeToParcel(Parcel dest, int flags) { - dest.writeByteArray(address); - dest.writeInt(prefixLength); - } - - /** - * Returns a comparator ordering IpPrefixes by length, shorter to longer. - * Contents of the address will break ties. - * @hide - */ - public static Comparator<IpPrefix> lengthComparator() { - return new Comparator<IpPrefix>() { - @Override - public int compare(IpPrefix prefix1, IpPrefix prefix2) { - if (prefix1.isIPv4()) { - if (prefix2.isIPv6()) return -1; - } else { - if (prefix2.isIPv4()) return 1; - } - final int p1len = prefix1.getPrefixLength(); - final int p2len = prefix2.getPrefixLength(); - if (p1len < p2len) return -1; - if (p2len < p1len) return 1; - final byte[] a1 = prefix1.address; - final byte[] a2 = prefix2.address; - final int len = a1.length < a2.length ? a1.length : a2.length; - for (int i = 0; i < len; ++i) { - if (a1[i] < a2[i]) return -1; - if (a1[i] > a2[i]) return 1; - } - if (a2.length < len) return 1; - if (a1.length < len) return -1; - return 0; - } - }; - } - - /** - * Implement the Parcelable interface. - */ - public static final @android.annotation.NonNull Creator<IpPrefix> CREATOR = - new Creator<IpPrefix>() { - public IpPrefix createFromParcel(Parcel in) { - byte[] address = in.createByteArray(); - int prefixLength = in.readInt(); - return new IpPrefix(address, prefixLength); - } - - public IpPrefix[] newArray(int size) { - return new IpPrefix[size]; - } - }; -} diff --git a/core/java/android/net/KeepalivePacketData.aidl b/core/java/android/net/KeepalivePacketData.aidl deleted file mode 100644 index d456b53fd188..000000000000 --- a/core/java/android/net/KeepalivePacketData.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -parcelable KeepalivePacketData; diff --git a/core/java/android/net/KeepalivePacketData.java b/core/java/android/net/KeepalivePacketData.java deleted file mode 100644 index 5877f1f4e269..000000000000 --- a/core/java/android/net/KeepalivePacketData.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS; -import static android.net.InvalidPacketException.ERROR_INVALID_PORT; - -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.util.Log; - -import com.android.net.module.util.IpUtils; - -import java.net.InetAddress; - -/** - * Represents the actual packets that are sent by the - * {@link android.net.SocketKeepalive} API. - * @hide - */ -@SystemApi -public class KeepalivePacketData { - private static final String TAG = "KeepalivePacketData"; - - /** Source IP address */ - @NonNull - private final InetAddress mSrcAddress; - - /** Destination IP address */ - @NonNull - private final InetAddress mDstAddress; - - /** Source port */ - private final int mSrcPort; - - /** Destination port */ - private final int mDstPort; - - /** Packet data. A raw byte string of packet data, not including the link-layer header. */ - private final byte[] mPacket; - - // Note: If you add new fields, please modify the parcelling code in the child classes. - - - // This should only be constructed via static factory methods, such as - // nattKeepalivePacket. - /** - * A holding class for data necessary to build a keepalive packet. - */ - protected KeepalivePacketData(@NonNull InetAddress srcAddress, - @IntRange(from = 0, to = 65535) int srcPort, @NonNull InetAddress dstAddress, - @IntRange(from = 0, to = 65535) int dstPort, - @NonNull byte[] data) throws InvalidPacketException { - this.mSrcAddress = srcAddress; - this.mDstAddress = dstAddress; - this.mSrcPort = srcPort; - this.mDstPort = dstPort; - this.mPacket = data; - - // Check we have two IP addresses of the same family. - if (srcAddress == null || dstAddress == null || !srcAddress.getClass().getName() - .equals(dstAddress.getClass().getName())) { - Log.e(TAG, "Invalid or mismatched InetAddresses in KeepalivePacketData"); - throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS); - } - - // Check the ports. - if (!IpUtils.isValidUdpOrTcpPort(srcPort) || !IpUtils.isValidUdpOrTcpPort(dstPort)) { - Log.e(TAG, "Invalid ports in KeepalivePacketData"); - throw new InvalidPacketException(ERROR_INVALID_PORT); - } - } - - /** Get source IP address. */ - @NonNull - public InetAddress getSrcAddress() { - return mSrcAddress; - } - - /** Get destination IP address. */ - @NonNull - public InetAddress getDstAddress() { - return mDstAddress; - } - - /** Get source port number. */ - public int getSrcPort() { - return mSrcPort; - } - - /** Get destination port number. */ - public int getDstPort() { - return mDstPort; - } - - /** - * Returns a byte array of the given packet data. - */ - @NonNull - public byte[] getPacket() { - return mPacket.clone(); - } - -} diff --git a/core/java/android/net/LinkAddress.aidl b/core/java/android/net/LinkAddress.aidl deleted file mode 100644 index 9c804db08d61..000000000000 --- a/core/java/android/net/LinkAddress.aidl +++ /dev/null @@ -1,21 +0,0 @@ -/** - * - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -@JavaOnlyStableParcelable parcelable LinkAddress; - diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java deleted file mode 100644 index 44d25a1ab0af..000000000000 --- a/core/java/android/net/LinkAddress.java +++ /dev/null @@ -1,549 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.system.OsConstants.IFA_F_DADFAILED; -import static android.system.OsConstants.IFA_F_DEPRECATED; -import static android.system.OsConstants.IFA_F_OPTIMISTIC; -import static android.system.OsConstants.IFA_F_PERMANENT; -import static android.system.OsConstants.IFA_F_TENTATIVE; -import static android.system.OsConstants.RT_SCOPE_HOST; -import static android.system.OsConstants.RT_SCOPE_LINK; -import static android.system.OsConstants.RT_SCOPE_SITE; -import static android.system.OsConstants.RT_SCOPE_UNIVERSE; - -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.SystemClock; -import android.util.Pair; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InterfaceAddress; -import java.net.UnknownHostException; -import java.util.Objects; - -/** - * Identifies an IP address on a network link. - * - * A {@code LinkAddress} consists of: - * <ul> - * <li>An IP address and prefix length (e.g., {@code 2001:db8::1/64} or {@code 192.0.2.1/24}). - * The address must be unicast, as multicast addresses cannot be assigned to interfaces. - * <li>Address flags: A bitmask of {@code OsConstants.IFA_F_*} values representing properties - * of the address (e.g., {@code android.system.OsConstants.IFA_F_OPTIMISTIC}). - * <li>Address scope: One of the {@code OsConstants.IFA_F_*} values; defines the scope in which - * the address is unique (e.g., - * {@code android.system.OsConstants.RT_SCOPE_LINK} or - * {@code android.system.OsConstants.RT_SCOPE_UNIVERSE}). - * </ul> - */ -public class LinkAddress implements Parcelable { - - /** - * Indicates the deprecation or expiration time is unknown - * @hide - */ - @SystemApi - public static final long LIFETIME_UNKNOWN = -1; - - /** - * Indicates this address is permanent. - * @hide - */ - @SystemApi - public static final long LIFETIME_PERMANENT = Long.MAX_VALUE; - - /** - * IPv4 or IPv6 address. - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - private InetAddress address; - - /** - * Prefix length. - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - private int prefixLength; - - /** - * Address flags. A bitmask of {@code IFA_F_*} values. Note that {@link #getFlags()} may not - * return these exact values. For example, it may set or clear the {@code IFA_F_DEPRECATED} - * flag depending on the current preferred lifetime. - */ - private int flags; - - /** - * Address scope. One of the RT_SCOPE_* constants. - */ - private int scope; - - /** - * The time, as reported by {@link SystemClock#elapsedRealtime}, when this LinkAddress will be - * or was deprecated. At the time existing connections can still use this address until it - * expires, but new connections should use the new address. {@link #LIFETIME_UNKNOWN} indicates - * this information is not available. {@link #LIFETIME_PERMANENT} indicates this - * {@link LinkAddress} will never be deprecated. - */ - private long deprecationTime; - - /** - * The time, as reported by {@link SystemClock#elapsedRealtime}, when this {@link LinkAddress} - * will expire and be removed from the interface. {@link #LIFETIME_UNKNOWN} indicates this - * information is not available. {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress} - * will never expire. - */ - private long expirationTime; - - /** - * Utility function to determines the scope of a unicast address. Per RFC 4291 section 2.5 and - * RFC 6724 section 3.2. - * @hide - */ - private static int scopeForUnicastAddress(InetAddress addr) { - if (addr.isAnyLocalAddress()) { - return RT_SCOPE_HOST; - } - - if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) { - return RT_SCOPE_LINK; - } - - // isSiteLocalAddress() returns true for private IPv4 addresses, but RFC 6724 section 3.2 - // says that they are assigned global scope. - if (!(addr instanceof Inet4Address) && addr.isSiteLocalAddress()) { - return RT_SCOPE_SITE; - } - - return RT_SCOPE_UNIVERSE; - } - - /** - * Utility function to check if |address| is a Unique Local IPv6 Unicast Address - * (a.k.a. "ULA"; RFC 4193). - * - * Per RFC 4193 section 8, fc00::/7 identifies these addresses. - */ - private boolean isIpv6ULA() { - if (isIpv6()) { - byte[] bytes = address.getAddress(); - return ((bytes[0] & (byte)0xfe) == (byte)0xfc); - } - return false; - } - - /** - * @return true if the address is IPv6. - * @hide - */ - @SystemApi - public boolean isIpv6() { - return address instanceof Inet6Address; - } - - /** - * For backward compatibility. - * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely - * just yet. - * @return true if the address is IPv6. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public boolean isIPv6() { - return isIpv6(); - } - - /** - * @return true if the address is IPv4 or is a mapped IPv4 address. - * @hide - */ - @SystemApi - public boolean isIpv4() { - return address instanceof Inet4Address; - } - - /** - * Utility function for the constructors. - */ - private void init(InetAddress address, int prefixLength, int flags, int scope, - long deprecationTime, long expirationTime) { - if (address == null || - address.isMulticastAddress() || - prefixLength < 0 || - (address instanceof Inet4Address && prefixLength > 32) || - (prefixLength > 128)) { - throw new IllegalArgumentException("Bad LinkAddress params " + address + - "/" + prefixLength); - } - - // deprecation time and expiration time must be both provided, or neither. - if ((deprecationTime == LIFETIME_UNKNOWN) != (expirationTime == LIFETIME_UNKNOWN)) { - throw new IllegalArgumentException( - "Must not specify only one of deprecation time and expiration time"); - } - - // deprecation time needs to be a positive value. - if (deprecationTime != LIFETIME_UNKNOWN && deprecationTime < 0) { - throw new IllegalArgumentException("invalid deprecation time " + deprecationTime); - } - - // expiration time needs to be a positive value. - if (expirationTime != LIFETIME_UNKNOWN && expirationTime < 0) { - throw new IllegalArgumentException("invalid expiration time " + expirationTime); - } - - // expiration time can't be earlier than deprecation time - if (deprecationTime != LIFETIME_UNKNOWN && expirationTime != LIFETIME_UNKNOWN - && expirationTime < deprecationTime) { - throw new IllegalArgumentException("expiration earlier than deprecation (" - + deprecationTime + ", " + expirationTime + ")"); - } - - this.address = address; - this.prefixLength = prefixLength; - this.flags = flags; - this.scope = scope; - this.deprecationTime = deprecationTime; - this.expirationTime = expirationTime; - } - - /** - * Constructs a new {@code LinkAddress} from an {@code InetAddress} and prefix length, with - * the specified flags and scope. Flags and scope are not checked for validity. - * - * @param address The IP address. - * @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6). - * @param flags A bitmask of {@code IFA_F_*} values representing properties of the address. - * @param scope An integer defining the scope in which the address is unique (e.g., - * {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}). - * @hide - */ - @SystemApi - public LinkAddress(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength, - int flags, int scope) { - init(address, prefixLength, flags, scope, LIFETIME_UNKNOWN, LIFETIME_UNKNOWN); - } - - /** - * Constructs a new {@code LinkAddress} from an {@code InetAddress}, prefix length, with - * the specified flags, scope, deprecation time, and expiration time. Flags and scope are not - * checked for validity. The value of the {@code IFA_F_DEPRECATED} and {@code IFA_F_PERMANENT} - * flag will be adjusted based on the passed-in lifetimes. - * - * @param address The IP address. - * @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6). - * @param flags A bitmask of {@code IFA_F_*} values representing properties of the address. - * @param scope An integer defining the scope in which the address is unique (e.g., - * {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}). - * @param deprecationTime The time, as reported by {@link SystemClock#elapsedRealtime}, when - * this {@link LinkAddress} will be or was deprecated. At the time - * existing connections can still use this address until it expires, but - * new connections should use the new address. {@link #LIFETIME_UNKNOWN} - * indicates this information is not available. - * {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress} will - * never be deprecated. - * @param expirationTime The time, as reported by {@link SystemClock#elapsedRealtime}, when this - * {@link LinkAddress} will expire and be removed from the interface. - * {@link #LIFETIME_UNKNOWN} indicates this information is not available. - * {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress} will - * never expire. - * @hide - */ - @SystemApi - public LinkAddress(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength, - int flags, int scope, long deprecationTime, long expirationTime) { - init(address, prefixLength, flags, scope, deprecationTime, expirationTime); - } - - /** - * Constructs a new {@code LinkAddress} from an {@code InetAddress} and a prefix length. - * The flags are set to zero and the scope is determined from the address. - * @param address The IP address. - * @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6). - * @hide - */ - @SystemApi - public LinkAddress(@NonNull InetAddress address, - @IntRange(from = 0, to = 128) int prefixLength) { - this(address, prefixLength, 0, 0); - this.scope = scopeForUnicastAddress(address); - } - - /** - * Constructs a new {@code LinkAddress} from an {@code InterfaceAddress}. - * The flags are set to zero and the scope is determined from the address. - * @param interfaceAddress The interface address. - * @hide - */ - public LinkAddress(@NonNull InterfaceAddress interfaceAddress) { - this(interfaceAddress.getAddress(), - interfaceAddress.getNetworkPrefixLength()); - } - - /** - * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or - * "2001:db8::1/64". The flags are set to zero and the scope is determined from the address. - * @param address The string to parse. - * @hide - */ - @SystemApi - public LinkAddress(@NonNull String address) { - this(address, 0, 0); - this.scope = scopeForUnicastAddress(this.address); - } - - /** - * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or - * "2001:db8::1/64", with the specified flags and scope. - * @param address The string to parse. - * @param flags The address flags. - * @param scope The address scope. - * @hide - */ - @SystemApi - public LinkAddress(@NonNull String address, int flags, int scope) { - // This may throw an IllegalArgumentException; catching it is the caller's responsibility. - // TODO: consider rejecting mapped IPv4 addresses such as "::ffff:192.0.2.5/24". - Pair<InetAddress, Integer> ipAndMask = NetworkUtils.parseIpAndMask(address); - init(ipAndMask.first, ipAndMask.second, flags, scope, LIFETIME_UNKNOWN, LIFETIME_UNKNOWN); - } - - /** - * Returns a string representation of this address, such as "192.0.2.1/24" or "2001:db8::1/64". - * The string representation does not contain the flags and scope, just the address and prefix - * length. - */ - @Override - public String toString() { - return address.getHostAddress() + "/" + prefixLength; - } - - /** - * Compares this {@code LinkAddress} instance against {@code obj}. Two addresses are equal if - * their address, prefix length, flags and scope are equal. Thus, for example, two addresses - * that have the same address and prefix length are not equal if one of them is deprecated and - * the other is not. - * - * @param obj the object to be tested for equality. - * @return {@code true} if both objects are equal, {@code false} otherwise. - */ - @Override - public boolean equals(Object obj) { - if (!(obj instanceof LinkAddress)) { - return false; - } - LinkAddress linkAddress = (LinkAddress) obj; - return this.address.equals(linkAddress.address) - && this.prefixLength == linkAddress.prefixLength - && this.flags == linkAddress.flags - && this.scope == linkAddress.scope - && this.deprecationTime == linkAddress.deprecationTime - && this.expirationTime == linkAddress.expirationTime; - } - - /** - * Returns a hashcode for this address. - */ - @Override - public int hashCode() { - return Objects.hash(address, prefixLength, flags, scope, deprecationTime, expirationTime); - } - - /** - * Determines whether this {@code LinkAddress} and the provided {@code LinkAddress} - * represent the same address. Two {@code LinkAddresses} represent the same address - * if they have the same IP address and prefix length, even if their properties are - * different. - * - * @param other the {@code LinkAddress} to compare to. - * @return {@code true} if both objects have the same address and prefix length, {@code false} - * otherwise. - * @hide - */ - @SystemApi - public boolean isSameAddressAs(@Nullable LinkAddress other) { - if (other == null) { - return false; - } - return address.equals(other.address) && prefixLength == other.prefixLength; - } - - /** - * Returns the {@link InetAddress} of this {@code LinkAddress}. - */ - public InetAddress getAddress() { - return address; - } - - /** - * Returns the prefix length of this {@code LinkAddress}. - */ - @IntRange(from = 0, to = 128) - public int getPrefixLength() { - return prefixLength; - } - - /** - * Returns the prefix length of this {@code LinkAddress}. - * TODO: Delete all callers and remove in favour of getPrefixLength(). - * @hide - */ - @UnsupportedAppUsage - @IntRange(from = 0, to = 128) - public int getNetworkPrefixLength() { - return getPrefixLength(); - } - - /** - * Returns the flags of this {@code LinkAddress}. - */ - public int getFlags() { - int flags = this.flags; - if (deprecationTime != LIFETIME_UNKNOWN) { - if (SystemClock.elapsedRealtime() >= deprecationTime) { - flags |= IFA_F_DEPRECATED; - } else { - // If deprecation time is in the future, or permanent. - flags &= ~IFA_F_DEPRECATED; - } - } - - if (expirationTime == LIFETIME_PERMANENT) { - flags |= IFA_F_PERMANENT; - } else if (expirationTime != LIFETIME_UNKNOWN) { - // If we know this address expired or will expire in the future, then this address - // should not be permanent. - flags &= ~IFA_F_PERMANENT; - } - - // Do no touch the original flags. Return the adjusted flags here. - return flags; - } - - /** - * Returns the scope of this {@code LinkAddress}. - */ - public int getScope() { - return scope; - } - - /** - * Get the deprecation time, as reported by {@link SystemClock#elapsedRealtime}, when this - * {@link LinkAddress} will be or was deprecated. At the time existing connections can still use - * this address until it expires, but new connections should use the new address. - * - * @return The deprecation time in milliseconds. {@link #LIFETIME_UNKNOWN} indicates this - * information is not available. {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress} - * will never be deprecated. - * - * @hide - */ - @SystemApi - public long getDeprecationTime() { - return deprecationTime; - } - - /** - * Get the expiration time, as reported by {@link SystemClock#elapsedRealtime}, when this - * {@link LinkAddress} will expire and be removed from the interface. - * - * @return The expiration time in milliseconds. {@link #LIFETIME_UNKNOWN} indicates this - * information is not available. {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress} - * will never expire. - * - * @hide - */ - @SystemApi - public long getExpirationTime() { - return expirationTime; - } - - /** - * Returns true if this {@code LinkAddress} is global scope and preferred (i.e., not currently - * deprecated). - * - * @hide - */ - @SystemApi - public boolean isGlobalPreferred() { - /** - * Note that addresses flagged as IFA_F_OPTIMISTIC are - * simultaneously flagged as IFA_F_TENTATIVE (when the tentative - * state has cleared either DAD has succeeded or failed, and both - * flags are cleared regardless). - */ - int flags = getFlags(); - return (scope == RT_SCOPE_UNIVERSE - && !isIpv6ULA() - && (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED)) == 0L - && ((flags & IFA_F_TENTATIVE) == 0L || (flags & IFA_F_OPTIMISTIC) != 0L)); - } - - /** - * Implement the Parcelable interface. - */ - public int describeContents() { - return 0; - } - - /** - * Implement the Parcelable interface. - */ - public void writeToParcel(Parcel dest, int flags) { - dest.writeByteArray(address.getAddress()); - dest.writeInt(prefixLength); - dest.writeInt(this.flags); - dest.writeInt(scope); - dest.writeLong(deprecationTime); - dest.writeLong(expirationTime); - } - - /** - * Implement the Parcelable interface. - */ - public static final @android.annotation.NonNull Creator<LinkAddress> CREATOR = - new Creator<LinkAddress>() { - public LinkAddress createFromParcel(Parcel in) { - InetAddress address = null; - try { - address = InetAddress.getByAddress(in.createByteArray()); - } catch (UnknownHostException e) { - // Nothing we can do here. When we call the constructor, we'll throw an - // IllegalArgumentException, because a LinkAddress can't have a null - // InetAddress. - } - int prefixLength = in.readInt(); - int flags = in.readInt(); - int scope = in.readInt(); - long deprecationTime = in.readLong(); - long expirationTime = in.readLong(); - return new LinkAddress(address, prefixLength, flags, scope, deprecationTime, - expirationTime); - } - - public LinkAddress[] newArray(int size) { - return new LinkAddress[size]; - } - }; -} diff --git a/core/java/android/net/LinkProperties.aidl b/core/java/android/net/LinkProperties.aidl deleted file mode 100644 index a8b3c7b0392f..000000000000 --- a/core/java/android/net/LinkProperties.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* -** -** Copyright (C) 2010 The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -package android.net; - -@JavaOnlyStableParcelable parcelable LinkProperties; diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java deleted file mode 100644 index 486e2d74dd05..000000000000 --- a/core/java/android/net/LinkProperties.java +++ /dev/null @@ -1,1823 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; - -import com.android.net.module.util.LinkPropertiesUtils; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Hashtable; -import java.util.List; -import java.util.Objects; -import java.util.StringJoiner; - -/** - * Describes the properties of a network link. - * - * A link represents a connection to a network. - * It may have multiple addresses and multiple gateways, - * multiple dns servers but only one http proxy and one - * network interface. - * - * Note that this is just a holder of data. Modifying it - * does not affect live networks. - * - */ -public final class LinkProperties implements Parcelable { - // The interface described by the network link. - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - private String mIfaceName; - private final ArrayList<LinkAddress> mLinkAddresses = new ArrayList<>(); - private final ArrayList<InetAddress> mDnses = new ArrayList<>(); - // PCSCF addresses are addresses of SIP proxies that only exist for the IMS core service. - private final ArrayList<InetAddress> mPcscfs = new ArrayList<InetAddress>(); - private final ArrayList<InetAddress> mValidatedPrivateDnses = new ArrayList<>(); - private boolean mUsePrivateDns; - private String mPrivateDnsServerName; - private String mDomains; - private ArrayList<RouteInfo> mRoutes = new ArrayList<>(); - private Inet4Address mDhcpServerAddress; - private ProxyInfo mHttpProxy; - private int mMtu; - // in the format "rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max" - private String mTcpBufferSizes; - private IpPrefix mNat64Prefix; - private boolean mWakeOnLanSupported; - private Uri mCaptivePortalApiUrl; - private CaptivePortalData mCaptivePortalData; - - /** - * Indicates whether parceling should preserve fields that are set based on permissions of - * the process receiving the {@link LinkProperties}. - */ - private final transient boolean mParcelSensitiveFields; - - private static final int MIN_MTU = 68; - - private static final int MIN_MTU_V6 = 1280; - - private static final int MAX_MTU = 10000; - - private static final int INET6_ADDR_LENGTH = 16; - - // Stores the properties of links that are "stacked" above this link. - // Indexed by interface name to allow modification and to prevent duplicates being added. - private Hashtable<String, LinkProperties> mStackedLinks = new Hashtable<>(); - - /** - * @hide - */ - @UnsupportedAppUsage(implicitMember = - "values()[Landroid/net/LinkProperties$ProvisioningChange;") - public enum ProvisioningChange { - @UnsupportedAppUsage - STILL_NOT_PROVISIONED, - @UnsupportedAppUsage - LOST_PROVISIONING, - @UnsupportedAppUsage - GAINED_PROVISIONING, - @UnsupportedAppUsage - STILL_PROVISIONED, - } - - /** - * Compare the provisioning states of two LinkProperties instances. - * - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static ProvisioningChange compareProvisioning( - LinkProperties before, LinkProperties after) { - if (before.isProvisioned() && after.isProvisioned()) { - // On dual-stack networks, DHCPv4 renewals can occasionally fail. - // When this happens, IPv6-reachable services continue to function - // normally but IPv4-only services (naturally) fail. - // - // When an application using an IPv4-only service reports a bad - // network condition to the framework, attempts to re-validate - // the network succeed (since we support IPv6-only networks) and - // nothing is changed. - // - // For users, this is confusing and unexpected behaviour, and is - // not necessarily easy to diagnose. Therefore, we treat changing - // from a dual-stack network to an IPv6-only network equivalent to - // a total loss of provisioning. - // - // For one such example of this, see b/18867306. - // - // Additionally, losing IPv6 provisioning can result in TCP - // connections getting stuck until timeouts fire and other - // baffling failures. Therefore, loss of either IPv4 or IPv6 on a - // previously dual-stack network is deemed a lost of provisioning. - if ((before.isIpv4Provisioned() && !after.isIpv4Provisioned()) - || (before.isIpv6Provisioned() && !after.isIpv6Provisioned())) { - return ProvisioningChange.LOST_PROVISIONING; - } - return ProvisioningChange.STILL_PROVISIONED; - } else if (before.isProvisioned() && !after.isProvisioned()) { - return ProvisioningChange.LOST_PROVISIONING; - } else if (!before.isProvisioned() && after.isProvisioned()) { - return ProvisioningChange.GAINED_PROVISIONING; - } else { // !before.isProvisioned() && !after.isProvisioned() - return ProvisioningChange.STILL_NOT_PROVISIONED; - } - } - - /** - * Constructs a new {@code LinkProperties} with default values. - */ - public LinkProperties() { - mParcelSensitiveFields = false; - } - - /** - * @hide - */ - @SystemApi - public LinkProperties(@Nullable LinkProperties source) { - this(source, false /* parcelSensitiveFields */); - } - - /** - * Create a copy of a {@link LinkProperties} that may preserve fields that were set - * based on the permissions of the process that originally received it. - * - * <p>By default {@link LinkProperties} does not preserve such fields during parceling, as - * they should not be shared outside of the process that receives them without appropriate - * checks. - * @param parcelSensitiveFields Whether the sensitive fields should be kept when parceling - * @hide - */ - @SystemApi - public LinkProperties(@Nullable LinkProperties source, boolean parcelSensitiveFields) { - mParcelSensitiveFields = parcelSensitiveFields; - if (source == null) return; - mIfaceName = source.mIfaceName; - mLinkAddresses.addAll(source.mLinkAddresses); - mDnses.addAll(source.mDnses); - mValidatedPrivateDnses.addAll(source.mValidatedPrivateDnses); - mUsePrivateDns = source.mUsePrivateDns; - mPrivateDnsServerName = source.mPrivateDnsServerName; - mPcscfs.addAll(source.mPcscfs); - mDomains = source.mDomains; - mRoutes.addAll(source.mRoutes); - mHttpProxy = (source.mHttpProxy == null) ? null : new ProxyInfo(source.mHttpProxy); - for (LinkProperties l: source.mStackedLinks.values()) { - addStackedLink(l); - } - setMtu(source.mMtu); - setDhcpServerAddress(source.getDhcpServerAddress()); - mTcpBufferSizes = source.mTcpBufferSizes; - mNat64Prefix = source.mNat64Prefix; - mWakeOnLanSupported = source.mWakeOnLanSupported; - mCaptivePortalApiUrl = source.mCaptivePortalApiUrl; - mCaptivePortalData = source.mCaptivePortalData; - } - - /** - * Sets the interface name for this link. All {@link RouteInfo} already set for this - * will have their interface changed to match this new value. - * - * @param iface The name of the network interface used for this link. - */ - public void setInterfaceName(@Nullable String iface) { - mIfaceName = iface; - ArrayList<RouteInfo> newRoutes = new ArrayList<>(mRoutes.size()); - for (RouteInfo route : mRoutes) { - newRoutes.add(routeWithInterface(route)); - } - mRoutes = newRoutes; - } - - /** - * Gets the interface name for this link. May be {@code null} if not set. - * - * @return The interface name set for this link or {@code null}. - */ - public @Nullable String getInterfaceName() { - return mIfaceName; - } - - /** - * @hide - */ - @SystemApi - public @NonNull List<String> getAllInterfaceNames() { - List<String> interfaceNames = new ArrayList<>(mStackedLinks.size() + 1); - if (mIfaceName != null) interfaceNames.add(mIfaceName); - for (LinkProperties stacked: mStackedLinks.values()) { - interfaceNames.addAll(stacked.getAllInterfaceNames()); - } - return interfaceNames; - } - - /** - * Returns all the addresses on this link. We often think of a link having a single address, - * however, particularly with Ipv6 several addresses are typical. Note that the - * {@code LinkProperties} actually contains {@link LinkAddress} objects which also include - * prefix lengths for each address. This is a simplified utility alternative to - * {@link LinkProperties#getLinkAddresses}. - * - * @return An unmodifiable {@link List} of {@link InetAddress} for this link. - * @hide - */ - @SystemApi - public @NonNull List<InetAddress> getAddresses() { - final List<InetAddress> addresses = new ArrayList<>(); - for (LinkAddress linkAddress : mLinkAddresses) { - addresses.add(linkAddress.getAddress()); - } - return Collections.unmodifiableList(addresses); - } - - /** - * Returns all the addresses on this link and all the links stacked above it. - * @hide - */ - @UnsupportedAppUsage - public @NonNull List<InetAddress> getAllAddresses() { - List<InetAddress> addresses = new ArrayList<>(); - for (LinkAddress linkAddress : mLinkAddresses) { - addresses.add(linkAddress.getAddress()); - } - for (LinkProperties stacked: mStackedLinks.values()) { - addresses.addAll(stacked.getAllAddresses()); - } - return addresses; - } - - private int findLinkAddressIndex(LinkAddress address) { - for (int i = 0; i < mLinkAddresses.size(); i++) { - if (mLinkAddresses.get(i).isSameAddressAs(address)) { - return i; - } - } - return -1; - } - - /** - * Adds a {@link LinkAddress} to this {@code LinkProperties} if a {@link LinkAddress} of the - * same address/prefix does not already exist. If it does exist it is replaced. - * @param address The {@code LinkAddress} to add. - * @return true if {@code address} was added or updated, false otherwise. - * @hide - */ - @SystemApi - public boolean addLinkAddress(@NonNull LinkAddress address) { - if (address == null) { - return false; - } - int i = findLinkAddressIndex(address); - if (i < 0) { - // Address was not present. Add it. - mLinkAddresses.add(address); - return true; - } else if (mLinkAddresses.get(i).equals(address)) { - // Address was present and has same properties. Do nothing. - return false; - } else { - // Address was present and has different properties. Update it. - mLinkAddresses.set(i, address); - return true; - } - } - - /** - * Removes a {@link LinkAddress} from this {@code LinkProperties}. Specifically, matches - * and {@link LinkAddress} with the same address and prefix. - * - * @param toRemove A {@link LinkAddress} specifying the address to remove. - * @return true if the address was removed, false if it did not exist. - * @hide - */ - @SystemApi - public boolean removeLinkAddress(@NonNull LinkAddress toRemove) { - int i = findLinkAddressIndex(toRemove); - if (i >= 0) { - mLinkAddresses.remove(i); - return true; - } - return false; - } - - /** - * Returns all the {@link LinkAddress} on this link. Typically a link will have - * one IPv4 address and one or more IPv6 addresses. - * - * @return An unmodifiable {@link List} of {@link LinkAddress} for this link. - */ - public @NonNull List<LinkAddress> getLinkAddresses() { - return Collections.unmodifiableList(mLinkAddresses); - } - - /** - * Returns all the addresses on this link and all the links stacked above it. - * @hide - */ - @SystemApi - public @NonNull List<LinkAddress> getAllLinkAddresses() { - List<LinkAddress> addresses = new ArrayList<>(mLinkAddresses); - for (LinkProperties stacked: mStackedLinks.values()) { - addresses.addAll(stacked.getAllLinkAddresses()); - } - return addresses; - } - - /** - * Replaces the {@link LinkAddress} in this {@code LinkProperties} with - * the given {@link Collection} of {@link LinkAddress}. - * - * @param addresses The {@link Collection} of {@link LinkAddress} to set in this - * object. - */ - public void setLinkAddresses(@NonNull Collection<LinkAddress> addresses) { - mLinkAddresses.clear(); - for (LinkAddress address: addresses) { - addLinkAddress(address); - } - } - - /** - * Adds the given {@link InetAddress} to the list of DNS servers, if not present. - * - * @param dnsServer The {@link InetAddress} to add to the list of DNS servers. - * @return true if the DNS server was added, false if it was already present. - * @hide - */ - @SystemApi - public boolean addDnsServer(@NonNull InetAddress dnsServer) { - if (dnsServer != null && !mDnses.contains(dnsServer)) { - mDnses.add(dnsServer); - return true; - } - return false; - } - - /** - * Removes the given {@link InetAddress} from the list of DNS servers. - * - * @param dnsServer The {@link InetAddress} to remove from the list of DNS servers. - * @return true if the DNS server was removed, false if it did not exist. - * @hide - */ - @SystemApi - public boolean removeDnsServer(@NonNull InetAddress dnsServer) { - return mDnses.remove(dnsServer); - } - - /** - * Replaces the DNS servers in this {@code LinkProperties} with - * the given {@link Collection} of {@link InetAddress} objects. - * - * @param dnsServers The {@link Collection} of DNS servers to set in this object. - */ - public void setDnsServers(@NonNull Collection<InetAddress> dnsServers) { - mDnses.clear(); - for (InetAddress dnsServer: dnsServers) { - addDnsServer(dnsServer); - } - } - - /** - * Returns all the {@link InetAddress} for DNS servers on this link. - * - * @return An unmodifiable {@link List} of {@link InetAddress} for DNS servers on - * this link. - */ - public @NonNull List<InetAddress> getDnsServers() { - return Collections.unmodifiableList(mDnses); - } - - /** - * Set whether private DNS is currently in use on this network. - * - * @param usePrivateDns The private DNS state. - * @hide - */ - @SystemApi - public void setUsePrivateDns(boolean usePrivateDns) { - mUsePrivateDns = usePrivateDns; - } - - /** - * Returns whether private DNS is currently in use on this network. When - * private DNS is in use, applications must not send unencrypted DNS - * queries as doing so could reveal private user information. Furthermore, - * if private DNS is in use and {@link #getPrivateDnsServerName} is not - * {@code null}, DNS queries must be sent to the specified DNS server. - * - * @return {@code true} if private DNS is in use, {@code false} otherwise. - */ - public boolean isPrivateDnsActive() { - return mUsePrivateDns; - } - - /** - * Set the name of the private DNS server to which private DNS queries - * should be sent when in strict mode. This value should be {@code null} - * when private DNS is off or in opportunistic mode. - * - * @param privateDnsServerName The private DNS server name. - * @hide - */ - @SystemApi - public void setPrivateDnsServerName(@Nullable String privateDnsServerName) { - mPrivateDnsServerName = privateDnsServerName; - } - - /** - * Set DHCP server address. - * - * @param serverAddress the server address to set. - */ - public void setDhcpServerAddress(@Nullable Inet4Address serverAddress) { - mDhcpServerAddress = serverAddress; - } - - /** - * Get DHCP server address - * - * @return The current DHCP server address. - */ - public @Nullable Inet4Address getDhcpServerAddress() { - return mDhcpServerAddress; - } - - /** - * Returns the private DNS server name that is in use. If not {@code null}, - * private DNS is in strict mode. In this mode, applications should ensure - * that all DNS queries are encrypted and sent to this hostname and that - * queries are only sent if the hostname's certificate is valid. If - * {@code null} and {@link #isPrivateDnsActive} is {@code true}, private - * DNS is in opportunistic mode, and applications should ensure that DNS - * queries are encrypted and sent to a DNS server returned by - * {@link #getDnsServers}. System DNS will handle each of these cases - * correctly, but applications implementing their own DNS lookups must make - * sure to follow these requirements. - * - * @return The private DNS server name. - */ - public @Nullable String getPrivateDnsServerName() { - return mPrivateDnsServerName; - } - - /** - * Adds the given {@link InetAddress} to the list of validated private DNS servers, - * if not present. This is distinct from the server name in that these are actually - * resolved addresses. - * - * @param dnsServer The {@link InetAddress} to add to the list of validated private DNS servers. - * @return true if the DNS server was added, false if it was already present. - * @hide - */ - public boolean addValidatedPrivateDnsServer(@NonNull InetAddress dnsServer) { - if (dnsServer != null && !mValidatedPrivateDnses.contains(dnsServer)) { - mValidatedPrivateDnses.add(dnsServer); - return true; - } - return false; - } - - /** - * Removes the given {@link InetAddress} from the list of validated private DNS servers. - * - * @param dnsServer The {@link InetAddress} to remove from the list of validated private DNS - * servers. - * @return true if the DNS server was removed, false if it did not exist. - * @hide - */ - public boolean removeValidatedPrivateDnsServer(@NonNull InetAddress dnsServer) { - return mValidatedPrivateDnses.remove(dnsServer); - } - - /** - * Replaces the validated private DNS servers in this {@code LinkProperties} with - * the given {@link Collection} of {@link InetAddress} objects. - * - * @param dnsServers The {@link Collection} of validated private DNS servers to set in this - * object. - * @hide - */ - @SystemApi - public void setValidatedPrivateDnsServers(@NonNull Collection<InetAddress> dnsServers) { - mValidatedPrivateDnses.clear(); - for (InetAddress dnsServer: dnsServers) { - addValidatedPrivateDnsServer(dnsServer); - } - } - - /** - * Returns all the {@link InetAddress} for validated private DNS servers on this link. - * These are resolved from the private DNS server name. - * - * @return An unmodifiable {@link List} of {@link InetAddress} for validated private - * DNS servers on this link. - * @hide - */ - @SystemApi - public @NonNull List<InetAddress> getValidatedPrivateDnsServers() { - return Collections.unmodifiableList(mValidatedPrivateDnses); - } - - /** - * Adds the given {@link InetAddress} to the list of PCSCF servers, if not present. - * - * @param pcscfServer The {@link InetAddress} to add to the list of PCSCF servers. - * @return true if the PCSCF server was added, false otherwise. - * @hide - */ - @SystemApi - public boolean addPcscfServer(@NonNull InetAddress pcscfServer) { - if (pcscfServer != null && !mPcscfs.contains(pcscfServer)) { - mPcscfs.add(pcscfServer); - return true; - } - return false; - } - - /** - * Removes the given {@link InetAddress} from the list of PCSCF servers. - * - * @param pcscfServer The {@link InetAddress} to remove from the list of PCSCF servers. - * @return true if the PCSCF server was removed, false otherwise. - * @hide - */ - public boolean removePcscfServer(@NonNull InetAddress pcscfServer) { - return mPcscfs.remove(pcscfServer); - } - - /** - * Replaces the PCSCF servers in this {@code LinkProperties} with - * the given {@link Collection} of {@link InetAddress} objects. - * - * @param pcscfServers The {@link Collection} of PCSCF servers to set in this object. - * @hide - */ - @SystemApi - public void setPcscfServers(@NonNull Collection<InetAddress> pcscfServers) { - mPcscfs.clear(); - for (InetAddress pcscfServer: pcscfServers) { - addPcscfServer(pcscfServer); - } - } - - /** - * Returns all the {@link InetAddress} for PCSCF servers on this link. - * - * @return An unmodifiable {@link List} of {@link InetAddress} for PCSCF servers on - * this link. - * @hide - */ - @SystemApi - public @NonNull List<InetAddress> getPcscfServers() { - return Collections.unmodifiableList(mPcscfs); - } - - /** - * Sets the DNS domain search path used on this link. - * - * @param domains A {@link String} listing in priority order the comma separated - * domains to search when resolving host names on this link. - */ - public void setDomains(@Nullable String domains) { - mDomains = domains; - } - - /** - * Get the DNS domains search path set for this link. May be {@code null} if not set. - * - * @return A {@link String} containing the comma separated domains to search when resolving host - * names on this link or {@code null}. - */ - public @Nullable String getDomains() { - return mDomains; - } - - /** - * Sets the Maximum Transmission Unit size to use on this link. This should not be used - * unless the system default (1500) is incorrect. Values less than 68 or greater than - * 10000 will be ignored. - * - * @param mtu The MTU to use for this link. - */ - public void setMtu(int mtu) { - mMtu = mtu; - } - - /** - * Gets any non-default MTU size set for this link. Note that if the default is being used - * this will return 0. - * - * @return The mtu value set for this link. - */ - public int getMtu() { - return mMtu; - } - - /** - * Sets the tcp buffers sizes to be used when this link is the system default. - * Should be of the form "rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max". - * - * @param tcpBufferSizes The tcp buffers sizes to use. - * - * @hide - */ - @SystemApi - public void setTcpBufferSizes(@Nullable String tcpBufferSizes) { - mTcpBufferSizes = tcpBufferSizes; - } - - /** - * Gets the tcp buffer sizes. May be {@code null} if not set. - * - * @return the tcp buffer sizes to use when this link is the system default or {@code null}. - * - * @hide - */ - @SystemApi - public @Nullable String getTcpBufferSizes() { - return mTcpBufferSizes; - } - - private RouteInfo routeWithInterface(RouteInfo route) { - return new RouteInfo( - route.getDestination(), - route.getGateway(), - mIfaceName, - route.getType(), - route.getMtu()); - } - - private int findRouteIndexByRouteKey(RouteInfo route) { - for (int i = 0; i < mRoutes.size(); i++) { - if (mRoutes.get(i).getRouteKey().equals(route.getRouteKey())) { - return i; - } - } - return -1; - } - - /** - * Adds a {@link RouteInfo} to this {@code LinkProperties}, if a {@link RouteInfo} - * with the same {@link RouteInfo.RouteKey} with different properties - * (e.g., different MTU), it will be updated. If the {@link RouteInfo} had an - * interface name set and that differs from the interface set for this - * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown. - * The proper course is to add either un-named or properly named {@link RouteInfo}. - * - * @param route A {@link RouteInfo} to add to this object. - * @return {@code true} was added or updated, false otherwise. - */ - public boolean addRoute(@NonNull RouteInfo route) { - String routeIface = route.getInterface(); - if (routeIface != null && !routeIface.equals(mIfaceName)) { - throw new IllegalArgumentException( - "Route added with non-matching interface: " + routeIface - + " vs. " + mIfaceName); - } - route = routeWithInterface(route); - - int i = findRouteIndexByRouteKey(route); - if (i == -1) { - // Route was not present. Add it. - mRoutes.add(route); - return true; - } else if (mRoutes.get(i).equals(route)) { - // Route was present and has same properties. Do nothing. - return false; - } else { - // Route was present and has different properties. Update it. - mRoutes.set(i, route); - return true; - } - } - - /** - * Removes a {@link RouteInfo} from this {@code LinkProperties}, if present. The route must - * specify an interface and the interface must match the interface of this - * {@code LinkProperties}, or it will not be removed. - * - * @param route A {@link RouteInfo} specifying the route to remove. - * @return {@code true} if the route was removed, {@code false} if it was not present. - * - * @hide - */ - @SystemApi - public boolean removeRoute(@NonNull RouteInfo route) { - return Objects.equals(mIfaceName, route.getInterface()) && mRoutes.remove(route); - } - - /** - * Returns all the {@link RouteInfo} set on this link. - * - * @return An unmodifiable {@link List} of {@link RouteInfo} for this link. - */ - public @NonNull List<RouteInfo> getRoutes() { - return Collections.unmodifiableList(mRoutes); - } - - /** - * Make sure this LinkProperties instance contains routes that cover the local subnet - * of its link addresses. Add any route that is missing. - * @hide - */ - public void ensureDirectlyConnectedRoutes() { - for (LinkAddress addr : mLinkAddresses) { - addRoute(new RouteInfo(addr, null, mIfaceName)); - } - } - - /** - * Returns all the routes on this link and all the links stacked above it. - * @hide - */ - @SystemApi - public @NonNull List<RouteInfo> getAllRoutes() { - List<RouteInfo> routes = new ArrayList<>(mRoutes); - for (LinkProperties stacked: mStackedLinks.values()) { - routes.addAll(stacked.getAllRoutes()); - } - return routes; - } - - /** - * Sets the recommended {@link ProxyInfo} to use on this link, or {@code null} for none. - * Note that Http Proxies are only a hint - the system recommends their use, but it does - * not enforce it and applications may ignore them. - * - * @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link. - */ - public void setHttpProxy(@Nullable ProxyInfo proxy) { - mHttpProxy = proxy; - } - - /** - * Gets the recommended {@link ProxyInfo} (or {@code null}) set on this link. - * - * @return The {@link ProxyInfo} set on this link or {@code null}. - */ - public @Nullable ProxyInfo getHttpProxy() { - return mHttpProxy; - } - - /** - * Returns the NAT64 prefix in use on this link, if any. - * - * @return the NAT64 prefix or {@code null}. - */ - public @Nullable IpPrefix getNat64Prefix() { - return mNat64Prefix; - } - - /** - * Sets the NAT64 prefix in use on this link. - * - * Currently, only 96-bit prefixes (i.e., where the 32-bit IPv4 address is at the end of the - * 128-bit IPv6 address) are supported or {@code null} for no prefix. - * - * @param prefix the NAT64 prefix. - */ - public void setNat64Prefix(@Nullable IpPrefix prefix) { - if (prefix != null && prefix.getPrefixLength() != 96) { - throw new IllegalArgumentException("Only 96-bit prefixes are supported: " + prefix); - } - mNat64Prefix = prefix; // IpPrefix objects are immutable. - } - - /** - * Adds a stacked link. - * - * If there is already a stacked link with the same interface name as link, - * that link is replaced with link. Otherwise, link is added to the list - * of stacked links. - * - * @param link The link to add. - * @return true if the link was stacked, false otherwise. - * @hide - */ - @UnsupportedAppUsage - public boolean addStackedLink(@NonNull LinkProperties link) { - if (link.getInterfaceName() != null) { - mStackedLinks.put(link.getInterfaceName(), link); - return true; - } - return false; - } - - /** - * Removes a stacked link. - * - * If there is a stacked link with the given interface name, it is - * removed. Otherwise, nothing changes. - * - * @param iface The interface name of the link to remove. - * @return true if the link was removed, false otherwise. - * @hide - */ - public boolean removeStackedLink(@NonNull String iface) { - LinkProperties removed = mStackedLinks.remove(iface); - return removed != null; - } - - /** - * Returns all the links stacked on top of this link. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public @NonNull List<LinkProperties> getStackedLinks() { - if (mStackedLinks.isEmpty()) { - return Collections.emptyList(); - } - final List<LinkProperties> stacked = new ArrayList<>(); - for (LinkProperties link : mStackedLinks.values()) { - stacked.add(new LinkProperties(link)); - } - return Collections.unmodifiableList(stacked); - } - - /** - * Clears this object to its initial state. - */ - public void clear() { - if (mParcelSensitiveFields) { - throw new UnsupportedOperationException( - "Cannot clear LinkProperties when parcelSensitiveFields is set"); - } - - mIfaceName = null; - mLinkAddresses.clear(); - mDnses.clear(); - mUsePrivateDns = false; - mPrivateDnsServerName = null; - mPcscfs.clear(); - mDomains = null; - mRoutes.clear(); - mHttpProxy = null; - mStackedLinks.clear(); - mMtu = 0; - mDhcpServerAddress = null; - mTcpBufferSizes = null; - mNat64Prefix = null; - mWakeOnLanSupported = false; - mCaptivePortalApiUrl = null; - mCaptivePortalData = null; - } - - /** - * Implement the Parcelable interface - */ - public int describeContents() { - return 0; - } - - @Override - public String toString() { - // Space as a separator, so no need for spaces at start/end of the individual fragments. - final StringJoiner resultJoiner = new StringJoiner(" ", "{", "}"); - - if (mIfaceName != null) { - resultJoiner.add("InterfaceName:"); - resultJoiner.add(mIfaceName); - } - - resultJoiner.add("LinkAddresses: ["); - if (!mLinkAddresses.isEmpty()) { - resultJoiner.add(TextUtils.join(",", mLinkAddresses)); - } - resultJoiner.add("]"); - - resultJoiner.add("DnsAddresses: ["); - if (!mDnses.isEmpty()) { - resultJoiner.add(TextUtils.join(",", mDnses)); - } - resultJoiner.add("]"); - - if (mUsePrivateDns) { - resultJoiner.add("UsePrivateDns: true"); - } - - if (mPrivateDnsServerName != null) { - resultJoiner.add("PrivateDnsServerName:"); - resultJoiner.add(mPrivateDnsServerName); - } - - if (!mPcscfs.isEmpty()) { - resultJoiner.add("PcscfAddresses: ["); - resultJoiner.add(TextUtils.join(",", mPcscfs)); - resultJoiner.add("]"); - } - - if (!mValidatedPrivateDnses.isEmpty()) { - final StringJoiner validatedPrivateDnsesJoiner = - new StringJoiner(",", "ValidatedPrivateDnsAddresses: [", "]"); - for (final InetAddress addr : mValidatedPrivateDnses) { - validatedPrivateDnsesJoiner.add(addr.getHostAddress()); - } - resultJoiner.add(validatedPrivateDnsesJoiner.toString()); - } - - resultJoiner.add("Domains:"); - resultJoiner.add(mDomains); - - resultJoiner.add("MTU:"); - resultJoiner.add(Integer.toString(mMtu)); - - if (mWakeOnLanSupported) { - resultJoiner.add("WakeOnLanSupported: true"); - } - - if (mDhcpServerAddress != null) { - resultJoiner.add("ServerAddress:"); - resultJoiner.add(mDhcpServerAddress.toString()); - } - - if (mCaptivePortalApiUrl != null) { - resultJoiner.add("CaptivePortalApiUrl: " + mCaptivePortalApiUrl); - } - - if (mCaptivePortalData != null) { - resultJoiner.add("CaptivePortalData: " + mCaptivePortalData); - } - - if (mTcpBufferSizes != null) { - resultJoiner.add("TcpBufferSizes:"); - resultJoiner.add(mTcpBufferSizes); - } - - resultJoiner.add("Routes: ["); - if (!mRoutes.isEmpty()) { - resultJoiner.add(TextUtils.join(",", mRoutes)); - } - resultJoiner.add("]"); - - if (mHttpProxy != null) { - resultJoiner.add("HttpProxy:"); - resultJoiner.add(mHttpProxy.toString()); - } - - if (mNat64Prefix != null) { - resultJoiner.add("Nat64Prefix:"); - resultJoiner.add(mNat64Prefix.toString()); - } - - final Collection<LinkProperties> stackedLinksValues = mStackedLinks.values(); - if (!stackedLinksValues.isEmpty()) { - final StringJoiner stackedLinksJoiner = new StringJoiner(",", "Stacked: [", "]"); - for (final LinkProperties lp : stackedLinksValues) { - stackedLinksJoiner.add("[ " + lp + " ]"); - } - resultJoiner.add(stackedLinksJoiner.toString()); - } - - return resultJoiner.toString(); - } - - /** - * Returns true if this link has an IPv4 address. - * - * @return {@code true} if there is an IPv4 address, {@code false} otherwise. - * @hide - */ - @SystemApi - public boolean hasIpv4Address() { - for (LinkAddress address : mLinkAddresses) { - if (address.getAddress() instanceof Inet4Address) { - return true; - } - } - return false; - } - - /** - * For backward compatibility. - * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely - * just yet. - * @return {@code true} if there is an IPv4 address, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public boolean hasIPv4Address() { - return hasIpv4Address(); - } - - /** - * Returns true if this link or any of its stacked interfaces has an IPv4 address. - * - * @return {@code true} if there is an IPv4 address, {@code false} otherwise. - */ - private boolean hasIpv4AddressOnInterface(String iface) { - // mIfaceName can be null. - return (Objects.equals(iface, mIfaceName) && hasIpv4Address()) - || (iface != null && mStackedLinks.containsKey(iface) - && mStackedLinks.get(iface).hasIpv4Address()); - } - - /** - * Returns true if this link has a global preferred IPv6 address. - * - * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise. - * @hide - */ - @SystemApi - public boolean hasGlobalIpv6Address() { - for (LinkAddress address : mLinkAddresses) { - if (address.getAddress() instanceof Inet6Address && address.isGlobalPreferred()) { - return true; - } - } - return false; - } - - /** - * Returns true if this link has an IPv4 unreachable default route. - * - * @return {@code true} if there is an IPv4 unreachable default route, {@code false} otherwise. - * @hide - */ - public boolean hasIpv4UnreachableDefaultRoute() { - for (RouteInfo r : mRoutes) { - if (r.isIPv4UnreachableDefault()) { - return true; - } - } - return false; - } - - /** - * For backward compatibility. - * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely - * just yet. - * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public boolean hasGlobalIPv6Address() { - return hasGlobalIpv6Address(); - } - - /** - * Returns true if this link has an IPv4 default route. - * - * @return {@code true} if there is an IPv4 default route, {@code false} otherwise. - * @hide - */ - @SystemApi - public boolean hasIpv4DefaultRoute() { - for (RouteInfo r : mRoutes) { - if (r.isIPv4Default()) { - return true; - } - } - return false; - } - - /** - * Returns true if this link has an IPv6 unreachable default route. - * - * @return {@code true} if there is an IPv6 unreachable default route, {@code false} otherwise. - * @hide - */ - public boolean hasIpv6UnreachableDefaultRoute() { - for (RouteInfo r : mRoutes) { - if (r.isIPv6UnreachableDefault()) { - return true; - } - } - return false; - } - - /** - * For backward compatibility. - * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely - * just yet. - * @return {@code true} if there is an IPv4 default route, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public boolean hasIPv4DefaultRoute() { - return hasIpv4DefaultRoute(); - } - - /** - * Returns true if this link has an IPv6 default route. - * - * @return {@code true} if there is an IPv6 default route, {@code false} otherwise. - * @hide - */ - @SystemApi - public boolean hasIpv6DefaultRoute() { - for (RouteInfo r : mRoutes) { - if (r.isIPv6Default()) { - return true; - } - } - return false; - } - - /** - * For backward compatibility. - * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely - * just yet. - * @return {@code true} if there is an IPv6 default route, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public boolean hasIPv6DefaultRoute() { - return hasIpv6DefaultRoute(); - } - - /** - * Returns true if this link has an IPv4 DNS server. - * - * @return {@code true} if there is an IPv4 DNS server, {@code false} otherwise. - * @hide - */ - @SystemApi - public boolean hasIpv4DnsServer() { - for (InetAddress ia : mDnses) { - if (ia instanceof Inet4Address) { - return true; - } - } - return false; - } - - /** - * For backward compatibility. - * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely - * just yet. - * @return {@code true} if there is an IPv4 DNS server, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public boolean hasIPv4DnsServer() { - return hasIpv4DnsServer(); - } - - /** - * Returns true if this link has an IPv6 DNS server. - * - * @return {@code true} if there is an IPv6 DNS server, {@code false} otherwise. - * @hide - */ - @SystemApi - public boolean hasIpv6DnsServer() { - for (InetAddress ia : mDnses) { - if (ia instanceof Inet6Address) { - return true; - } - } - return false; - } - - /** - * For backward compatibility. - * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely - * just yet. - * @return {@code true} if there is an IPv6 DNS server, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public boolean hasIPv6DnsServer() { - return hasIpv6DnsServer(); - } - - /** - * Returns true if this link has an IPv4 PCSCF server. - * - * @return {@code true} if there is an IPv4 PCSCF server, {@code false} otherwise. - * @hide - */ - public boolean hasIpv4PcscfServer() { - for (InetAddress ia : mPcscfs) { - if (ia instanceof Inet4Address) { - return true; - } - } - return false; - } - - /** - * Returns true if this link has an IPv6 PCSCF server. - * - * @return {@code true} if there is an IPv6 PCSCF server, {@code false} otherwise. - * @hide - */ - public boolean hasIpv6PcscfServer() { - for (InetAddress ia : mPcscfs) { - if (ia instanceof Inet6Address) { - return true; - } - } - return false; - } - - /** - * Returns true if this link is provisioned for global IPv4 connectivity. - * This requires an IP address, default route, and DNS server. - * - * @return {@code true} if the link is provisioned, {@code false} otherwise. - * @hide - */ - @SystemApi - public boolean isIpv4Provisioned() { - return (hasIpv4Address() - && hasIpv4DefaultRoute() - && hasIpv4DnsServer()); - } - - /** - * Returns true if this link is provisioned for global IPv6 connectivity. - * This requires an IP address, default route, and DNS server. - * - * @return {@code true} if the link is provisioned, {@code false} otherwise. - * @hide - */ - @SystemApi - public boolean isIpv6Provisioned() { - return (hasGlobalIpv6Address() - && hasIpv6DefaultRoute() - && hasIpv6DnsServer()); - } - - /** - * For backward compatibility. - * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely - * just yet. - * @return {@code true} if the link is provisioned, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public boolean isIPv6Provisioned() { - return isIpv6Provisioned(); - } - - - /** - * Returns true if this link is provisioned for global connectivity, - * for at least one Internet Protocol family. - * - * @return {@code true} if the link is provisioned, {@code false} otherwise. - * @hide - */ - @SystemApi - public boolean isProvisioned() { - return (isIpv4Provisioned() || isIpv6Provisioned()); - } - - /** - * Evaluate whether the {@link InetAddress} is considered reachable. - * - * @return {@code true} if the given {@link InetAddress} is considered reachable, - * {@code false} otherwise. - * @hide - */ - @SystemApi - public boolean isReachable(@NonNull InetAddress ip) { - final List<RouteInfo> allRoutes = getAllRoutes(); - // If we don't have a route to this IP address, it's not reachable. - final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, ip); - if (bestRoute == null) { - return false; - } - - // TODO: better source address evaluation for destination addresses. - - if (ip instanceof Inet4Address) { - // For IPv4, it suffices for now to simply have any address. - return hasIpv4AddressOnInterface(bestRoute.getInterface()); - } else if (ip instanceof Inet6Address) { - if (ip.isLinkLocalAddress()) { - // For now, just make sure link-local destinations have - // scopedIds set, since transmits will generally fail otherwise. - // TODO: verify it matches the ifindex of one of the interfaces. - return (((Inet6Address)ip).getScopeId() != 0); - } else { - // For non-link-local destinations check that either the best route - // is directly connected or that some global preferred address exists. - // TODO: reconsider all cases (disconnected ULA networks, ...). - return (!bestRoute.hasGateway() || hasGlobalIpv6Address()); - } - } - - return false; - } - - /** - * Compares this {@code LinkProperties} interface name against the target - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage - public boolean isIdenticalInterfaceName(@NonNull LinkProperties target) { - return LinkPropertiesUtils.isIdenticalInterfaceName(target, this); - } - - /** - * Compares this {@code LinkProperties} DHCP server address against the target - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - public boolean isIdenticalDhcpServerAddress(@NonNull LinkProperties target) { - return Objects.equals(mDhcpServerAddress, target.mDhcpServerAddress); - } - - /** - * Compares this {@code LinkProperties} interface addresses against the target - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage - public boolean isIdenticalAddresses(@NonNull LinkProperties target) { - return LinkPropertiesUtils.isIdenticalAddresses(target, this); - } - - /** - * Compares this {@code LinkProperties} DNS addresses against the target - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage - public boolean isIdenticalDnses(@NonNull LinkProperties target) { - return LinkPropertiesUtils.isIdenticalDnses(target, this); - } - - /** - * Compares this {@code LinkProperties} private DNS settings against the - * target. - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - public boolean isIdenticalPrivateDns(@NonNull LinkProperties target) { - return (isPrivateDnsActive() == target.isPrivateDnsActive() - && TextUtils.equals(getPrivateDnsServerName(), - target.getPrivateDnsServerName())); - } - - /** - * Compares this {@code LinkProperties} validated private DNS addresses against - * the target - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - public boolean isIdenticalValidatedPrivateDnses(@NonNull LinkProperties target) { - Collection<InetAddress> targetDnses = target.getValidatedPrivateDnsServers(); - return (mValidatedPrivateDnses.size() == targetDnses.size()) - ? mValidatedPrivateDnses.containsAll(targetDnses) : false; - } - - /** - * Compares this {@code LinkProperties} PCSCF addresses against the target - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - public boolean isIdenticalPcscfs(@NonNull LinkProperties target) { - Collection<InetAddress> targetPcscfs = target.getPcscfServers(); - return (mPcscfs.size() == targetPcscfs.size()) ? - mPcscfs.containsAll(targetPcscfs) : false; - } - - /** - * Compares this {@code LinkProperties} Routes against the target - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage - public boolean isIdenticalRoutes(@NonNull LinkProperties target) { - return LinkPropertiesUtils.isIdenticalRoutes(target, this); - } - - /** - * Compares this {@code LinkProperties} HttpProxy against the target - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - public boolean isIdenticalHttpProxy(@NonNull LinkProperties target) { - return LinkPropertiesUtils.isIdenticalHttpProxy(target, this); - } - - /** - * Compares this {@code LinkProperties} stacked links against the target - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public boolean isIdenticalStackedLinks(@NonNull LinkProperties target) { - if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) { - return false; - } - for (LinkProperties stacked : mStackedLinks.values()) { - // Hashtable values can never be null. - String iface = stacked.getInterfaceName(); - if (!stacked.equals(target.mStackedLinks.get(iface))) { - return false; - } - } - return true; - } - - /** - * Compares this {@code LinkProperties} MTU against the target - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - public boolean isIdenticalMtu(@NonNull LinkProperties target) { - return getMtu() == target.getMtu(); - } - - /** - * Compares this {@code LinkProperties} Tcp buffer sizes against the target. - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - public boolean isIdenticalTcpBufferSizes(@NonNull LinkProperties target) { - return Objects.equals(mTcpBufferSizes, target.mTcpBufferSizes); - } - - /** - * Compares this {@code LinkProperties} NAT64 prefix against the target. - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - public boolean isIdenticalNat64Prefix(@NonNull LinkProperties target) { - return Objects.equals(mNat64Prefix, target.mNat64Prefix); - } - - /** - * Compares this {@code LinkProperties} WakeOnLan supported against the target. - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - public boolean isIdenticalWakeOnLan(LinkProperties target) { - return isWakeOnLanSupported() == target.isWakeOnLanSupported(); - } - - /** - * Compares this {@code LinkProperties}'s CaptivePortalApiUrl against the target. - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - public boolean isIdenticalCaptivePortalApiUrl(LinkProperties target) { - return Objects.equals(mCaptivePortalApiUrl, target.mCaptivePortalApiUrl); - } - - /** - * Compares this {@code LinkProperties}'s CaptivePortalData against the target. - * - * @param target LinkProperties to compare. - * @return {@code true} if both are identical, {@code false} otherwise. - * @hide - */ - public boolean isIdenticalCaptivePortalData(LinkProperties target) { - return Objects.equals(mCaptivePortalData, target.mCaptivePortalData); - } - - /** - * Set whether the network interface supports WakeOnLAN - * - * @param supported WakeOnLAN supported value - * - * @hide - */ - public void setWakeOnLanSupported(boolean supported) { - mWakeOnLanSupported = supported; - } - - /** - * Returns whether the network interface supports WakeOnLAN - * - * @return {@code true} if interface supports WakeOnLAN, {@code false} otherwise. - */ - public boolean isWakeOnLanSupported() { - return mWakeOnLanSupported; - } - - /** - * Set the URL of the captive portal API endpoint to get more information about the network. - * @hide - */ - @SystemApi - public void setCaptivePortalApiUrl(@Nullable Uri url) { - mCaptivePortalApiUrl = url; - } - - /** - * Get the URL of the captive portal API endpoint to get more information about the network. - * - * <p>This is null unless the application has - * {@link android.Manifest.permission.NETWORK_SETTINGS} or - * {@link NetworkStack#PERMISSION_MAINLINE_NETWORK_STACK} permissions, and the network provided - * the URL. - * @hide - */ - @SystemApi - @Nullable - public Uri getCaptivePortalApiUrl() { - return mCaptivePortalApiUrl; - } - - /** - * Set the CaptivePortalData obtained from the captive portal API (RFC7710bis). - * @hide - */ - @SystemApi - public void setCaptivePortalData(@Nullable CaptivePortalData data) { - mCaptivePortalData = data; - } - - /** - * Get the CaptivePortalData obtained from the captive portal API (RFC7710bis). - * - * <p>This is null unless the application has - * {@link android.Manifest.permission.NETWORK_SETTINGS} or - * {@link NetworkStack#PERMISSION_MAINLINE_NETWORK_STACK} permissions. - * @hide - */ - @SystemApi - @Nullable - public CaptivePortalData getCaptivePortalData() { - return mCaptivePortalData; - } - - /** - * Compares this {@code LinkProperties} instance against the target - * LinkProperties in {@code obj}. Two LinkPropertieses are equal if - * all their fields are equal in values. - * - * For collection fields, such as mDnses, containsAll() is used to check - * if two collections contains the same elements, independent of order. - * There are two thoughts regarding containsAll() - * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal. - * 2. Worst case performance is O(n^2). - * - * @param obj the object to be tested for equality. - * @return {@code true} if both objects are equal, {@code false} otherwise. - */ - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - - if (!(obj instanceof LinkProperties)) return false; - - LinkProperties target = (LinkProperties) obj; - /* - * This method does not check that stacked interfaces are equal, because - * stacked interfaces are not so much a property of the link as a - * description of connections between links. - */ - return isIdenticalInterfaceName(target) - && isIdenticalAddresses(target) - && isIdenticalDhcpServerAddress(target) - && isIdenticalDnses(target) - && isIdenticalPrivateDns(target) - && isIdenticalValidatedPrivateDnses(target) - && isIdenticalPcscfs(target) - && isIdenticalRoutes(target) - && isIdenticalHttpProxy(target) - && isIdenticalStackedLinks(target) - && isIdenticalMtu(target) - && isIdenticalTcpBufferSizes(target) - && isIdenticalNat64Prefix(target) - && isIdenticalWakeOnLan(target) - && isIdenticalCaptivePortalApiUrl(target) - && isIdenticalCaptivePortalData(target); - } - - /** - * Generate hashcode based on significant fields - * - * Equal objects must produce the same hash code, while unequal objects - * may have the same hash codes. - */ - @Override - public int hashCode() { - return ((null == mIfaceName) ? 0 : mIfaceName.hashCode() - + mLinkAddresses.size() * 31 - + mDnses.size() * 37 - + mValidatedPrivateDnses.size() * 61 - + ((null == mDomains) ? 0 : mDomains.hashCode()) - + mRoutes.size() * 41 - + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode()) - + mStackedLinks.hashCode() * 47) - + mMtu * 51 - + ((null == mTcpBufferSizes) ? 0 : mTcpBufferSizes.hashCode()) - + (mUsePrivateDns ? 57 : 0) - + ((null == mDhcpServerAddress) ? 0 : mDhcpServerAddress.hashCode()) - + mPcscfs.size() * 67 - + ((null == mPrivateDnsServerName) ? 0 : mPrivateDnsServerName.hashCode()) - + Objects.hash(mNat64Prefix) - + (mWakeOnLanSupported ? 71 : 0) - + Objects.hash(mCaptivePortalApiUrl, mCaptivePortalData); - } - - /** - * Implement the Parcelable interface. - */ - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(getInterfaceName()); - dest.writeInt(mLinkAddresses.size()); - for (LinkAddress linkAddress : mLinkAddresses) { - dest.writeParcelable(linkAddress, flags); - } - - writeAddresses(dest, mDnses); - writeAddresses(dest, mValidatedPrivateDnses); - dest.writeBoolean(mUsePrivateDns); - dest.writeString(mPrivateDnsServerName); - writeAddresses(dest, mPcscfs); - dest.writeString(mDomains); - writeAddress(dest, mDhcpServerAddress); - dest.writeInt(mMtu); - dest.writeString(mTcpBufferSizes); - dest.writeInt(mRoutes.size()); - for (RouteInfo route : mRoutes) { - dest.writeParcelable(route, flags); - } - - if (mHttpProxy != null) { - dest.writeByte((byte)1); - dest.writeParcelable(mHttpProxy, flags); - } else { - dest.writeByte((byte)0); - } - dest.writeParcelable(mNat64Prefix, 0); - - ArrayList<LinkProperties> stackedLinks = new ArrayList<>(mStackedLinks.values()); - dest.writeList(stackedLinks); - - dest.writeBoolean(mWakeOnLanSupported); - dest.writeParcelable(mParcelSensitiveFields ? mCaptivePortalApiUrl : null, 0); - dest.writeParcelable(mParcelSensitiveFields ? mCaptivePortalData : null, 0); - } - - private static void writeAddresses(@NonNull Parcel dest, @NonNull List<InetAddress> list) { - dest.writeInt(list.size()); - for (InetAddress d : list) { - writeAddress(dest, d); - } - } - - private static void writeAddress(@NonNull Parcel dest, @Nullable InetAddress addr) { - byte[] addressBytes = (addr == null ? null : addr.getAddress()); - dest.writeByteArray(addressBytes); - if (addr instanceof Inet6Address) { - final Inet6Address v6Addr = (Inet6Address) addr; - final boolean hasScopeId = v6Addr.getScopeId() != 0; - dest.writeBoolean(hasScopeId); - if (hasScopeId) dest.writeInt(v6Addr.getScopeId()); - } - } - - @Nullable - private static InetAddress readAddress(@NonNull Parcel p) throws UnknownHostException { - final byte[] addr = p.createByteArray(); - if (addr == null) return null; - - if (addr.length == INET6_ADDR_LENGTH) { - final boolean hasScopeId = p.readBoolean(); - final int scopeId = hasScopeId ? p.readInt() : 0; - return Inet6Address.getByAddress(null /* host */, addr, scopeId); - } - - return InetAddress.getByAddress(addr); - } - - /** - * Implement the Parcelable interface. - */ - public static final @android.annotation.NonNull Creator<LinkProperties> CREATOR = - new Creator<LinkProperties>() { - public LinkProperties createFromParcel(Parcel in) { - LinkProperties netProp = new LinkProperties(); - - String iface = in.readString(); - if (iface != null) { - netProp.setInterfaceName(iface); - } - int addressCount = in.readInt(); - for (int i = 0; i < addressCount; i++) { - netProp.addLinkAddress(in.readParcelable(null)); - } - addressCount = in.readInt(); - for (int i = 0; i < addressCount; i++) { - try { - netProp.addDnsServer(readAddress(in)); - } catch (UnknownHostException e) { } - } - addressCount = in.readInt(); - for (int i = 0; i < addressCount; i++) { - try { - netProp.addValidatedPrivateDnsServer(readAddress(in)); - } catch (UnknownHostException e) { } - } - netProp.setUsePrivateDns(in.readBoolean()); - netProp.setPrivateDnsServerName(in.readString()); - addressCount = in.readInt(); - for (int i = 0; i < addressCount; i++) { - try { - netProp.addPcscfServer(readAddress(in)); - } catch (UnknownHostException e) { } - } - netProp.setDomains(in.readString()); - try { - netProp.setDhcpServerAddress((Inet4Address) InetAddress - .getByAddress(in.createByteArray())); - } catch (UnknownHostException e) { } - netProp.setMtu(in.readInt()); - netProp.setTcpBufferSizes(in.readString()); - addressCount = in.readInt(); - for (int i = 0; i < addressCount; i++) { - netProp.addRoute(in.readParcelable(null)); - } - if (in.readByte() == 1) { - netProp.setHttpProxy(in.readParcelable(null)); - } - netProp.setNat64Prefix(in.readParcelable(null)); - ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>(); - in.readList(stackedLinks, LinkProperties.class.getClassLoader()); - for (LinkProperties stackedLink: stackedLinks) { - netProp.addStackedLink(stackedLink); - } - netProp.setWakeOnLanSupported(in.readBoolean()); - - netProp.setCaptivePortalApiUrl(in.readParcelable(null)); - netProp.setCaptivePortalData(in.readParcelable(null)); - return netProp; - } - - public LinkProperties[] newArray(int size) { - return new LinkProperties[size]; - } - }; - - /** - * Check the valid MTU range based on IPv4 or IPv6. - * @hide - */ - public static boolean isValidMtu(int mtu, boolean ipv6) { - if (ipv6) { - return mtu >= MIN_MTU_V6 && mtu <= MAX_MTU; - } else { - return mtu >= MIN_MTU && mtu <= MAX_MTU; - } - } -} diff --git a/core/java/android/net/MacAddress.aidl b/core/java/android/net/MacAddress.aidl deleted file mode 100644 index 48a18a7ac821..000000000000 --- a/core/java/android/net/MacAddress.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/** - * - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -@JavaOnlyStableParcelable parcelable MacAddress; diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java deleted file mode 100644 index c7116b41e80a..000000000000 --- a/core/java/android/net/MacAddress.java +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.compat.annotation.UnsupportedAppUsage; -import android.net.wifi.WifiInfo; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; - -import com.android.internal.util.Preconditions; -import com.android.net.module.util.MacAddressUtils; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.net.Inet6Address; -import java.net.UnknownHostException; -import java.security.SecureRandom; -import java.util.Arrays; - -/** - * Representation of a MAC address. - * - * This class only supports 48 bits long addresses and does not support 64 bits long addresses. - * Instances of this class are immutable. This class provides implementations of hashCode() - * and equals() that make it suitable for use as keys in standard implementations of - * {@link java.util.Map}. - */ -public final class MacAddress implements Parcelable { - - private static final int ETHER_ADDR_LEN = 6; - private static final byte[] ETHER_ADDR_BROADCAST = addr(0xff, 0xff, 0xff, 0xff, 0xff, 0xff); - - /** - * The MacAddress representing the unique broadcast MAC address. - */ - public static final MacAddress BROADCAST_ADDRESS = MacAddress.fromBytes(ETHER_ADDR_BROADCAST); - - /** - * The MacAddress zero MAC address. - * - * <p>Not publicly exposed or treated specially since the OUI 00:00:00 is registered. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final MacAddress ALL_ZEROS_ADDRESS = new MacAddress(0); - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "TYPE_" }, value = { - TYPE_UNKNOWN, - TYPE_UNICAST, - TYPE_MULTICAST, - TYPE_BROADCAST, - }) - public @interface MacAddressType { } - - /** @hide Indicates a MAC address of unknown type. */ - public static final int TYPE_UNKNOWN = 0; - /** Indicates a MAC address is a unicast address. */ - public static final int TYPE_UNICAST = 1; - /** Indicates a MAC address is a multicast address. */ - public static final int TYPE_MULTICAST = 2; - /** Indicates a MAC address is the broadcast address. */ - public static final int TYPE_BROADCAST = 3; - - private static final long VALID_LONG_MASK = (1L << 48) - 1; - private static final long LOCALLY_ASSIGNED_MASK = MacAddress.fromString("2:0:0:0:0:0").mAddr; - private static final long MULTICAST_MASK = MacAddress.fromString("1:0:0:0:0:0").mAddr; - private static final long OUI_MASK = MacAddress.fromString("ff:ff:ff:0:0:0").mAddr; - private static final long NIC_MASK = MacAddress.fromString("0:0:0:ff:ff:ff").mAddr; - private static final MacAddress BASE_GOOGLE_MAC = MacAddress.fromString("da:a1:19:0:0:0"); - /** Default wifi MAC address used for a special purpose **/ - private static final MacAddress DEFAULT_MAC_ADDRESS = - MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); - - // Internal representation of the MAC address as a single 8 byte long. - // The encoding scheme sets the two most significant bytes to 0. The 6 bytes of the - // MAC address are encoded in the 6 least significant bytes of the long, where the first - // byte of the array is mapped to the 3rd highest logical byte of the long, the second - // byte of the array is mapped to the 4th highest logical byte of the long, and so on. - private final long mAddr; - - private MacAddress(long addr) { - mAddr = (VALID_LONG_MASK & addr); - } - - /** - * Returns the type of this address. - * - * @return the int constant representing the MAC address type of this MacAddress. - */ - public @MacAddressType int getAddressType() { - if (equals(BROADCAST_ADDRESS)) { - return TYPE_BROADCAST; - } - if ((mAddr & MULTICAST_MASK) != 0) { - return TYPE_MULTICAST; - } - return TYPE_UNICAST; - } - - /** - * @return true if this MacAddress is a locally assigned address. - */ - public boolean isLocallyAssigned() { - return (mAddr & LOCALLY_ASSIGNED_MASK) != 0; - } - - /** - * Convert this MacAddress to a byte array. - * - * The returned array is in network order. For example, if this MacAddress is 1:2:3:4:5:6, - * the returned array is [1, 2, 3, 4, 5, 6]. - * - * @return a byte array representation of this MacAddress. - */ - public @NonNull byte[] toByteArray() { - return byteAddrFromLongAddr(mAddr); - } - - /** - * Returns a human-readable representation of this MacAddress. - * The exact format is implementation-dependent and should not be assumed to have any - * particular format. - */ - @Override - public @NonNull String toString() { - return stringAddrFromLongAddr(mAddr); - } - - /** - * @return a String representation of the OUI part of this MacAddress made of 3 hexadecimal - * numbers in [0,ff] joined by ':' characters. - */ - public @NonNull String toOuiString() { - return String.format( - "%02x:%02x:%02x", (mAddr >> 40) & 0xff, (mAddr >> 32) & 0xff, (mAddr >> 24) & 0xff); - } - - @Override - public int hashCode() { - return (int) ((mAddr >> 32) ^ mAddr); - } - - @Override - public boolean equals(Object o) { - return (o instanceof MacAddress) && ((MacAddress) o).mAddr == mAddr; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeLong(mAddr); - } - - @Override - public int describeContents() { - return 0; - } - - public static final @android.annotation.NonNull Parcelable.Creator<MacAddress> CREATOR = - new Parcelable.Creator<MacAddress>() { - public MacAddress createFromParcel(Parcel in) { - return new MacAddress(in.readLong()); - } - - public MacAddress[] newArray(int size) { - return new MacAddress[size]; - } - }; - - /** - * Returns true if the given byte array is an valid MAC address. - * A valid byte array representation for a MacAddress is a non-null array of length 6. - * - * @param addr a byte array. - * @return true if the given byte array is not null and has the length of a MAC address. - * - * @hide - */ - public static boolean isMacAddress(byte[] addr) { - return MacAddressUtils.isMacAddress(addr); - } - - /** - * Returns the MAC address type of the MAC address represented by the given byte array, - * or null if the given byte array does not represent a MAC address. - * A valid byte array representation for a MacAddress is a non-null array of length 6. - * - * @param addr a byte array representing a MAC address. - * @return the int constant representing the MAC address type of the MAC address represented - * by the given byte array, or type UNKNOWN if the byte array is not a valid MAC address. - * - * @hide - */ - public static int macAddressType(byte[] addr) { - if (!isMacAddress(addr)) { - return TYPE_UNKNOWN; - } - return MacAddress.fromBytes(addr).getAddressType(); - } - - /** - * Converts a String representation of a MAC address to a byte array representation. - * A valid String representation for a MacAddress is a series of 6 values in the - * range [0,ff] printed in hexadecimal and joined by ':' characters. - * - * @param addr a String representation of a MAC address. - * @return the byte representation of the MAC address. - * @throws IllegalArgumentException if the given String is not a valid representation. - * - * @hide - */ - public static @NonNull byte[] byteAddrFromStringAddr(String addr) { - Preconditions.checkNotNull(addr); - String[] parts = addr.split(":"); - if (parts.length != ETHER_ADDR_LEN) { - throw new IllegalArgumentException(addr + " was not a valid MAC address"); - } - byte[] bytes = new byte[ETHER_ADDR_LEN]; - for (int i = 0; i < ETHER_ADDR_LEN; i++) { - int x = Integer.valueOf(parts[i], 16); - if (x < 0 || 0xff < x) { - throw new IllegalArgumentException(addr + "was not a valid MAC address"); - } - bytes[i] = (byte) x; - } - return bytes; - } - - /** - * Converts a byte array representation of a MAC address to a String representation made - * of 6 hexadecimal numbers in [0,ff] joined by ':' characters. - * A valid byte array representation for a MacAddress is a non-null array of length 6. - * - * @param addr a byte array representation of a MAC address. - * @return the String representation of the MAC address. - * @throws IllegalArgumentException if the given byte array is not a valid representation. - * - * @hide - */ - public static @NonNull String stringAddrFromByteAddr(byte[] addr) { - if (!isMacAddress(addr)) { - return null; - } - return String.format("%02x:%02x:%02x:%02x:%02x:%02x", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - } - - private static byte[] byteAddrFromLongAddr(long addr) { - return MacAddressUtils.byteAddrFromLongAddr(addr); - } - - private static long longAddrFromByteAddr(byte[] addr) { - return MacAddressUtils.longAddrFromByteAddr(addr); - } - - // Internal conversion function equivalent to longAddrFromByteAddr(byteAddrFromStringAddr(addr)) - // that avoids the allocation of an intermediary byte[]. - private static long longAddrFromStringAddr(String addr) { - Preconditions.checkNotNull(addr); - String[] parts = addr.split(":"); - if (parts.length != ETHER_ADDR_LEN) { - throw new IllegalArgumentException(addr + " was not a valid MAC address"); - } - long longAddr = 0; - for (int i = 0; i < parts.length; i++) { - int x = Integer.valueOf(parts[i], 16); - if (x < 0 || 0xff < x) { - throw new IllegalArgumentException(addr + "was not a valid MAC address"); - } - longAddr = x + (longAddr << 8); - } - return longAddr; - } - - // Internal conversion function equivalent to stringAddrFromByteAddr(byteAddrFromLongAddr(addr)) - // that avoids the allocation of an intermediary byte[]. - private static @NonNull String stringAddrFromLongAddr(long addr) { - return String.format("%02x:%02x:%02x:%02x:%02x:%02x", - (addr >> 40) & 0xff, - (addr >> 32) & 0xff, - (addr >> 24) & 0xff, - (addr >> 16) & 0xff, - (addr >> 8) & 0xff, - addr & 0xff); - } - - /** - * Creates a MacAddress from the given String representation. A valid String representation - * for a MacAddress is a series of 6 values in the range [0,ff] printed in hexadecimal - * and joined by ':' characters. - * - * @param addr a String representation of a MAC address. - * @return the MacAddress corresponding to the given String representation. - * @throws IllegalArgumentException if the given String is not a valid representation. - */ - public static @NonNull MacAddress fromString(@NonNull String addr) { - return new MacAddress(longAddrFromStringAddr(addr)); - } - - /** - * Creates a MacAddress from the given byte array representation. - * A valid byte array representation for a MacAddress is a non-null array of length 6. - * - * @param addr a byte array representation of a MAC address. - * @return the MacAddress corresponding to the given byte array representation. - * @throws IllegalArgumentException if the given byte array is not a valid representation. - */ - public static @NonNull MacAddress fromBytes(@NonNull byte[] addr) { - return new MacAddress(longAddrFromByteAddr(addr)); - } - - /** - * Returns a generated MAC address whose 24 least significant bits constituting the - * NIC part of the address are randomly selected and has Google OUI base. - * - * The locally assigned bit is always set to 1. The multicast bit is always set to 0. - * - * @return a random locally assigned, unicast MacAddress with Google OUI. - * - * @hide - */ - public static @NonNull MacAddress createRandomUnicastAddressWithGoogleBase() { - return MacAddressUtils.createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom()); - } - - // Convenience function for working around the lack of byte literals. - private static byte[] addr(int... in) { - if (in.length != ETHER_ADDR_LEN) { - throw new IllegalArgumentException(Arrays.toString(in) - + " was not an array with length equal to " + ETHER_ADDR_LEN); - } - byte[] out = new byte[ETHER_ADDR_LEN]; - for (int i = 0; i < ETHER_ADDR_LEN; i++) { - out[i] = (byte) in[i]; - } - return out; - } - - /** - * Checks if this MAC Address matches the provided range. - * - * @param baseAddress MacAddress representing the base address to compare with. - * @param mask MacAddress representing the mask to use during comparison. - * @return true if this MAC Address matches the given range. - * - */ - public boolean matches(@NonNull MacAddress baseAddress, @NonNull MacAddress mask) { - Preconditions.checkNotNull(baseAddress); - Preconditions.checkNotNull(mask); - return (mAddr & mask.mAddr) == (baseAddress.mAddr & mask.mAddr); - } - - /** - * Create a link-local Inet6Address from the MAC address. The EUI-48 MAC address is converted - * to an EUI-64 MAC address per RFC 4291. The resulting EUI-64 is used to construct a link-local - * IPv6 address per RFC 4862. - * - * @return A link-local Inet6Address constructed from the MAC address. - */ - public @Nullable Inet6Address getLinkLocalIpv6FromEui48Mac() { - byte[] macEui48Bytes = toByteArray(); - byte[] addr = new byte[16]; - - addr[0] = (byte) 0xfe; - addr[1] = (byte) 0x80; - addr[8] = (byte) (macEui48Bytes[0] ^ (byte) 0x02); // flip the link-local bit - addr[9] = macEui48Bytes[1]; - addr[10] = macEui48Bytes[2]; - addr[11] = (byte) 0xff; - addr[12] = (byte) 0xfe; - addr[13] = macEui48Bytes[3]; - addr[14] = macEui48Bytes[4]; - addr[15] = macEui48Bytes[5]; - - try { - return Inet6Address.getByAddress(null, addr, 0); - } catch (UnknownHostException e) { - return null; - } - } -} diff --git a/core/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java deleted file mode 100644 index c4f8fc281f25..000000000000 --- a/core/java/android/net/NattKeepalivePacketData.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS; -import static android.net.InvalidPacketException.ERROR_INVALID_PORT; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; -import android.system.OsConstants; - -import com.android.net.module.util.IpUtils; - -import java.net.Inet4Address; -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Objects; - -/** @hide */ -@SystemApi -public final class NattKeepalivePacketData extends KeepalivePacketData implements Parcelable { - private static final int IPV4_HEADER_LENGTH = 20; - private static final int UDP_HEADER_LENGTH = 8; - - // This should only be constructed via static factory methods, such as - // nattKeepalivePacket - public NattKeepalivePacketData(@NonNull InetAddress srcAddress, int srcPort, - @NonNull InetAddress dstAddress, int dstPort, @NonNull byte[] data) throws - InvalidPacketException { - super(srcAddress, srcPort, dstAddress, dstPort, data); - } - - /** - * Factory method to create Nat-T keepalive packet structure. - * @hide - */ - public static NattKeepalivePacketData nattKeepalivePacket( - InetAddress srcAddress, int srcPort, InetAddress dstAddress, int dstPort) - throws InvalidPacketException { - - if (!(srcAddress instanceof Inet4Address) || !(dstAddress instanceof Inet4Address)) { - throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS); - } - - if (dstPort != NattSocketKeepalive.NATT_PORT) { - throw new InvalidPacketException(ERROR_INVALID_PORT); - } - - int length = IPV4_HEADER_LENGTH + UDP_HEADER_LENGTH + 1; - ByteBuffer buf = ByteBuffer.allocate(length); - buf.order(ByteOrder.BIG_ENDIAN); - buf.putShort((short) 0x4500); // IP version and TOS - buf.putShort((short) length); - buf.putInt(0); // ID, flags, offset - buf.put((byte) 64); // TTL - buf.put((byte) OsConstants.IPPROTO_UDP); - int ipChecksumOffset = buf.position(); - buf.putShort((short) 0); // IP checksum - buf.put(srcAddress.getAddress()); - buf.put(dstAddress.getAddress()); - buf.putShort((short) srcPort); - buf.putShort((short) dstPort); - buf.putShort((short) (length - 20)); // UDP length - int udpChecksumOffset = buf.position(); - buf.putShort((short) 0); // UDP checksum - buf.put((byte) 0xff); // NAT-T keepalive - buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0)); - buf.putShort(udpChecksumOffset, IpUtils.udpChecksum(buf, 0, IPV4_HEADER_LENGTH)); - - return new NattKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array()); - } - - /** Parcelable Implementation */ - public int describeContents() { - return 0; - } - - /** Write to parcel */ - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeString(getSrcAddress().getHostAddress()); - out.writeString(getDstAddress().getHostAddress()); - out.writeInt(getSrcPort()); - out.writeInt(getDstPort()); - } - - /** Parcelable Creator */ - public static final @NonNull Parcelable.Creator<NattKeepalivePacketData> CREATOR = - new Parcelable.Creator<NattKeepalivePacketData>() { - public NattKeepalivePacketData createFromParcel(Parcel in) { - final InetAddress srcAddress = - InetAddresses.parseNumericAddress(in.readString()); - final InetAddress dstAddress = - InetAddresses.parseNumericAddress(in.readString()); - final int srcPort = in.readInt(); - final int dstPort = in.readInt(); - try { - return NattKeepalivePacketData.nattKeepalivePacket(srcAddress, srcPort, - dstAddress, dstPort); - } catch (InvalidPacketException e) { - throw new IllegalArgumentException( - "Invalid NAT-T keepalive data: " + e.getError()); - } - } - - public NattKeepalivePacketData[] newArray(int size) { - return new NattKeepalivePacketData[size]; - } - }; - - @Override - public boolean equals(@Nullable final Object o) { - if (!(o instanceof NattKeepalivePacketData)) return false; - final NattKeepalivePacketData other = (NattKeepalivePacketData) o; - final InetAddress srcAddress = getSrcAddress(); - final InetAddress dstAddress = getDstAddress(); - return srcAddress.equals(other.getSrcAddress()) - && dstAddress.equals(other.getDstAddress()) - && getSrcPort() == other.getSrcPort() - && getDstPort() == other.getDstPort(); - } - - @Override - public int hashCode() { - return Objects.hash(getSrcAddress(), getDstAddress(), getSrcPort(), getDstPort()); - } -} diff --git a/core/java/android/net/NattSocketKeepalive.java b/core/java/android/net/NattSocketKeepalive.java deleted file mode 100644 index a15d165e65e7..000000000000 --- a/core/java/android/net/NattSocketKeepalive.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; -import android.os.ParcelFileDescriptor; -import android.os.RemoteException; -import android.util.Log; - -import java.net.InetAddress; -import java.util.concurrent.Executor; - -/** @hide */ -public final class NattSocketKeepalive extends SocketKeepalive { - /** The NAT-T destination port for IPsec */ - public static final int NATT_PORT = 4500; - - @NonNull private final InetAddress mSource; - @NonNull private final InetAddress mDestination; - private final int mResourceId; - - NattSocketKeepalive(@NonNull IConnectivityManager service, - @NonNull Network network, - @NonNull ParcelFileDescriptor pfd, - int resourceId, - @NonNull InetAddress source, - @NonNull InetAddress destination, - @NonNull Executor executor, - @NonNull Callback callback) { - super(service, network, pfd, executor, callback); - mSource = source; - mDestination = destination; - mResourceId = resourceId; - } - - @Override - void startImpl(int intervalSec) { - mExecutor.execute(() -> { - try { - mService.startNattKeepaliveWithFd(mNetwork, mPfd, mResourceId, - intervalSec, mCallback, - mSource.getHostAddress(), mDestination.getHostAddress()); - } catch (RemoteException e) { - Log.e(TAG, "Error starting socket keepalive: ", e); - throw e.rethrowFromSystemServer(); - } - }); - } - - @Override - void stopImpl() { - mExecutor.execute(() -> { - try { - if (mSlot != null) { - mService.stopKeepalive(mNetwork, mSlot); - } - } catch (RemoteException e) { - Log.e(TAG, "Error stopping socket keepalive: ", e); - throw e.rethrowFromSystemServer(); - } - }); - } -} diff --git a/core/java/android/net/Network.aidl b/core/java/android/net/Network.aidl deleted file mode 100644 index 05622025bf33..000000000000 --- a/core/java/android/net/Network.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* -** -** Copyright (C) 2014 The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -package android.net; - -@JavaOnlyStableParcelable parcelable Network; diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java deleted file mode 100644 index b07bd68a0f50..000000000000 --- a/core/java/android/net/Network.java +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; -import android.os.Parcel; -import android.os.ParcelFileDescriptor; -import android.os.Parcelable; -import android.system.ErrnoException; -import android.system.Os; -import android.system.OsConstants; -import android.util.proto.ProtoOutputStream; - -import com.android.internal.annotations.GuardedBy; -import com.android.okhttp.internalandroidapi.Dns; -import com.android.okhttp.internalandroidapi.HttpURLConnectionFactory; - -import libcore.io.IoUtils; - -import java.io.FileDescriptor; -import java.io.IOException; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.SocketException; -import java.net.URL; -import java.net.URLConnection; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.concurrent.TimeUnit; - -import javax.net.SocketFactory; - -/** - * Identifies a {@code Network}. This is supplied to applications via - * {@link ConnectivityManager.NetworkCallback} in response to the active - * {@link ConnectivityManager#requestNetwork} or passive - * {@link ConnectivityManager#registerNetworkCallback} calls. - * It is used to direct traffic to the given {@code Network}, either on a {@link Socket} basis - * through a targeted {@link SocketFactory} or process-wide via - * {@link ConnectivityManager#bindProcessToNetwork}. - */ -public class Network implements Parcelable { - - /** - * The unique id of the network. - * @hide - */ - @UnsupportedAppUsage - public final int netId; - - // Objects used to perform per-network operations such as getSocketFactory - // and openConnection, and a lock to protect access to them. - private volatile NetworkBoundSocketFactory mNetworkBoundSocketFactory = null; - // mUrlConnectionFactory is initialized lazily when it is first needed. - @GuardedBy("mLock") - private HttpURLConnectionFactory mUrlConnectionFactory; - private final Object mLock = new Object(); - - // Default connection pool values. These are evaluated at startup, just - // like the OkHttp code. Also like the OkHttp code, we will throw parse - // exceptions at class loading time if the properties are set but are not - // valid integers. - private static final boolean httpKeepAlive = - Boolean.parseBoolean(System.getProperty("http.keepAlive", "true")); - private static final int httpMaxConnections = - httpKeepAlive ? Integer.parseInt(System.getProperty("http.maxConnections", "5")) : 0; - private static final long httpKeepAliveDurationMs = - Long.parseLong(System.getProperty("http.keepAliveDuration", "300000")); // 5 minutes. - // Value used to obfuscate network handle longs. - // The HANDLE_MAGIC value MUST be kept in sync with the corresponding - // value in the native/android/net.c NDK implementation. - private static final long HANDLE_MAGIC = 0xcafed00dL; - private static final int HANDLE_MAGIC_SIZE = 32; - - // A boolean to control how getAllByName()/getByName() behaves in the face - // of Private DNS. - // - // When true, these calls will request that DNS resolution bypass any - // Private DNS that might otherwise apply. Use of this feature is restricted - // and permission checks are made by netd (attempts to bypass Private DNS - // without appropriate permission are silently turned into vanilla DNS - // requests). This only affects DNS queries made using this network object. - // - // It it not parceled to receivers because (a) it can be set or cleared at - // anytime and (b) receivers should be explicit about attempts to bypass - // Private DNS so that the intent of the code is easily determined and - // code search audits are possible. - private final transient boolean mPrivateDnsBypass; - - /** - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public Network(int netId) { - this(netId, false); - } - - /** - * @hide - */ - public Network(int netId, boolean privateDnsBypass) { - this.netId = netId; - this.mPrivateDnsBypass = privateDnsBypass; - } - - /** - * @hide - */ - @SystemApi - public Network(@NonNull Network that) { - this(that.netId, that.mPrivateDnsBypass); - } - - /** - * Operates the same as {@code InetAddress.getAllByName} except that host - * resolution is done on this network. - * - * @param host the hostname or literal IP string to be resolved. - * @return the array of addresses associated with the specified host. - * @throws UnknownHostException if the address lookup fails. - */ - public InetAddress[] getAllByName(String host) throws UnknownHostException { - return InetAddress.getAllByNameOnNet(host, getNetIdForResolv()); - } - - /** - * Operates the same as {@code InetAddress.getByName} except that host - * resolution is done on this network. - * - * @param host the hostname to be resolved to an address or {@code null}. - * @return the {@code InetAddress} instance representing the host. - * @throws UnknownHostException - * if the address lookup fails. - */ - public InetAddress getByName(String host) throws UnknownHostException { - return InetAddress.getByNameOnNet(host, getNetIdForResolv()); - } - - /** - * Obtain a Network object for which Private DNS is to be bypassed when attempting - * to use {@link #getAllByName(String)}/{@link #getByName(String)} methods on the given - * instance for hostname resolution. - * - * @hide - */ - @SystemApi - public @NonNull Network getPrivateDnsBypassingCopy() { - return new Network(netId, true); - } - - /** - * Get the unique id of the network. - * - * @hide - */ - @SystemApi - public int getNetId() { - return netId; - } - - /** - * Returns a netid marked with the Private DNS bypass flag. - * - * This flag must be kept in sync with the NETID_USE_LOCAL_NAMESERVERS flag - * in system/netd/include/NetdClient.h. - * - * @hide - */ - public int getNetIdForResolv() { - return mPrivateDnsBypass - ? (int) (0x80000000L | (long) netId) // Non-portable DNS resolution flag. - : netId; - } - - /** - * A {@code SocketFactory} that produces {@code Socket}'s bound to this network. - */ - private class NetworkBoundSocketFactory extends SocketFactory { - private Socket connectToHost(String host, int port, SocketAddress localAddress) - throws IOException { - // Lookup addresses only on this Network. - InetAddress[] hostAddresses = getAllByName(host); - // Try all addresses. - for (int i = 0; i < hostAddresses.length; i++) { - try { - Socket socket = createSocket(); - boolean failed = true; - try { - if (localAddress != null) socket.bind(localAddress); - socket.connect(new InetSocketAddress(hostAddresses[i], port)); - failed = false; - return socket; - } finally { - if (failed) IoUtils.closeQuietly(socket); - } - } catch (IOException e) { - if (i == (hostAddresses.length - 1)) throw e; - } - } - throw new UnknownHostException(host); - } - - @Override - public Socket createSocket(String host, int port, InetAddress localHost, int localPort) - throws IOException { - return connectToHost(host, port, new InetSocketAddress(localHost, localPort)); - } - - @Override - public Socket createSocket(InetAddress address, int port, InetAddress localAddress, - int localPort) throws IOException { - Socket socket = createSocket(); - boolean failed = true; - try { - socket.bind(new InetSocketAddress(localAddress, localPort)); - socket.connect(new InetSocketAddress(address, port)); - failed = false; - } finally { - if (failed) IoUtils.closeQuietly(socket); - } - return socket; - } - - @Override - public Socket createSocket(InetAddress host, int port) throws IOException { - Socket socket = createSocket(); - boolean failed = true; - try { - socket.connect(new InetSocketAddress(host, port)); - failed = false; - } finally { - if (failed) IoUtils.closeQuietly(socket); - } - return socket; - } - - @Override - public Socket createSocket(String host, int port) throws IOException { - return connectToHost(host, port, null); - } - - @Override - public Socket createSocket() throws IOException { - Socket socket = new Socket(); - boolean failed = true; - try { - bindSocket(socket); - failed = false; - } finally { - if (failed) IoUtils.closeQuietly(socket); - } - return socket; - } - } - - /** - * Returns a {@link SocketFactory} bound to this network. Any {@link Socket} created by - * this factory will have its traffic sent over this {@code Network}. Note that if this - * {@code Network} ever disconnects, this factory and any {@link Socket} it produced in the - * past or future will cease to work. - * - * @return a {@link SocketFactory} which produces {@link Socket} instances bound to this - * {@code Network}. - */ - public SocketFactory getSocketFactory() { - if (mNetworkBoundSocketFactory == null) { - synchronized (mLock) { - if (mNetworkBoundSocketFactory == null) { - mNetworkBoundSocketFactory = new NetworkBoundSocketFactory(); - } - } - } - return mNetworkBoundSocketFactory; - } - - private static HttpURLConnectionFactory createUrlConnectionFactory(Dns dnsLookup) { - // Set configuration on the HttpURLConnectionFactory that will be good for all - // connections created by this Network. Configuration that might vary is left - // until openConnection() and passed as arguments. - HttpURLConnectionFactory urlConnectionFactory = new HttpURLConnectionFactory(); - urlConnectionFactory.setDns(dnsLookup); // Let traffic go via dnsLookup - // A private connection pool just for this Network. - urlConnectionFactory.setNewConnectionPool(httpMaxConnections, - httpKeepAliveDurationMs, TimeUnit.MILLISECONDS); - return urlConnectionFactory; - } - - /** - * Opens the specified {@link URL} on this {@code Network}, such that all traffic will be sent - * on this Network. The URL protocol must be {@code HTTP} or {@code HTTPS}. - * - * @return a {@code URLConnection} to the resource referred to by this URL. - * @throws MalformedURLException if the URL protocol is not HTTP or HTTPS. - * @throws IOException if an error occurs while opening the connection. - * @see java.net.URL#openConnection() - */ - public URLConnection openConnection(URL url) throws IOException { - final ConnectivityManager cm = ConnectivityManager.getInstanceOrNull(); - if (cm == null) { - throw new IOException("No ConnectivityManager yet constructed, please construct one"); - } - // TODO: Should this be optimized to avoid fetching the global proxy for every request? - final ProxyInfo proxyInfo = cm.getProxyForNetwork(this); - final java.net.Proxy proxy; - if (proxyInfo != null) { - proxy = proxyInfo.makeProxy(); - } else { - proxy = java.net.Proxy.NO_PROXY; - } - return openConnection(url, proxy); - } - - /** - * Opens the specified {@link URL} on this {@code Network}, such that all traffic will be sent - * on this Network. The URL protocol must be {@code HTTP} or {@code HTTPS}. - * - * @param proxy the proxy through which the connection will be established. - * @return a {@code URLConnection} to the resource referred to by this URL. - * @throws MalformedURLException if the URL protocol is not HTTP or HTTPS. - * @throws IllegalArgumentException if the argument proxy is null. - * @throws IOException if an error occurs while opening the connection. - * @see java.net.URL#openConnection() - */ - public URLConnection openConnection(URL url, java.net.Proxy proxy) throws IOException { - if (proxy == null) throw new IllegalArgumentException("proxy is null"); - // TODO: This creates a connection pool and host resolver for - // every Network object, instead of one for every NetId. This is - // suboptimal, because an app could potentially have more than one - // Network object for the same NetId, causing increased memory footprint - // and performance penalties due to lack of connection reuse (connection - // setup time, congestion window growth time, etc.). - // - // Instead, investigate only having one connection pool and host resolver - // for every NetId, perhaps by using a static HashMap of NetIds to - // connection pools and host resolvers. The tricky part is deciding when - // to remove a map entry; a WeakHashMap shouldn't be used because whether - // a Network is referenced doesn't correlate with whether a new Network - // will be instantiated in the near future with the same NetID. A good - // solution would involve purging empty (or when all connections are timed - // out) ConnectionPools. - final HttpURLConnectionFactory urlConnectionFactory; - synchronized (mLock) { - if (mUrlConnectionFactory == null) { - Dns dnsLookup = hostname -> Arrays.asList(getAllByName(hostname)); - mUrlConnectionFactory = createUrlConnectionFactory(dnsLookup); - } - urlConnectionFactory = mUrlConnectionFactory; - } - SocketFactory socketFactory = getSocketFactory(); - return urlConnectionFactory.openConnection(url, socketFactory, proxy); - } - - /** - * Binds the specified {@link DatagramSocket} to this {@code Network}. All data traffic on the - * socket will be sent on this {@code Network}, irrespective of any process-wide network binding - * set by {@link ConnectivityManager#bindProcessToNetwork}. The socket must not be - * connected. - */ - public void bindSocket(DatagramSocket socket) throws IOException { - // Query a property of the underlying socket to ensure that the socket's file descriptor - // exists, is available to bind to a network and is not closed. - socket.getReuseAddress(); - final ParcelFileDescriptor pfd = ParcelFileDescriptor.fromDatagramSocket(socket); - bindSocket(pfd.getFileDescriptor()); - // ParcelFileDescriptor.fromSocket() creates a dup of the original fd. The original and the - // dup share the underlying socket in the kernel. The socket is never truly closed until the - // last fd pointing to the socket being closed. So close the dup one after binding the - // socket to control the lifetime of the dup fd. - pfd.close(); - } - - /** - * Binds the specified {@link Socket} to this {@code Network}. All data traffic on the socket - * will be sent on this {@code Network}, irrespective of any process-wide network binding set by - * {@link ConnectivityManager#bindProcessToNetwork}. The socket must not be connected. - */ - public void bindSocket(Socket socket) throws IOException { - // Query a property of the underlying socket to ensure that the socket's file descriptor - // exists, is available to bind to a network and is not closed. - socket.getReuseAddress(); - final ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket); - bindSocket(pfd.getFileDescriptor()); - // ParcelFileDescriptor.fromSocket() creates a dup of the original fd. The original and the - // dup share the underlying socket in the kernel. The socket is never truly closed until the - // last fd pointing to the socket being closed. So close the dup one after binding the - // socket to control the lifetime of the dup fd. - pfd.close(); - } - - /** - * Binds the specified {@link FileDescriptor} to this {@code Network}. All data traffic on the - * socket represented by this file descriptor will be sent on this {@code Network}, - * irrespective of any process-wide network binding set by - * {@link ConnectivityManager#bindProcessToNetwork}. The socket must not be connected. - */ - public void bindSocket(FileDescriptor fd) throws IOException { - try { - final SocketAddress peer = Os.getpeername(fd); - final InetAddress inetPeer = ((InetSocketAddress) peer).getAddress(); - if (!inetPeer.isAnyLocalAddress()) { - // Apparently, the kernel doesn't update a connected UDP socket's - // routing upon mark changes. - throw new SocketException("Socket is connected"); - } - } catch (ErrnoException e) { - // getpeername() failed. - if (e.errno != OsConstants.ENOTCONN) { - throw e.rethrowAsSocketException(); - } - } catch (ClassCastException e) { - // Wasn't an InetSocketAddress. - throw new SocketException("Only AF_INET/AF_INET6 sockets supported"); - } - - final int err = NetworkUtils.bindSocketToNetwork(fd, netId); - if (err != 0) { - // bindSocketToNetwork returns negative errno. - throw new ErrnoException("Binding socket to network " + netId, -err) - .rethrowAsSocketException(); - } - } - - /** - * Returns a {@link Network} object given a handle returned from {@link #getNetworkHandle}. - * - * @param networkHandle a handle returned from {@link #getNetworkHandle}. - * @return A {@link Network} object derived from {@code networkHandle}. - */ - public static Network fromNetworkHandle(long networkHandle) { - if (networkHandle == 0) { - throw new IllegalArgumentException( - "Network.fromNetworkHandle refusing to instantiate NETID_UNSET Network."); - } - if ((networkHandle & ((1L << HANDLE_MAGIC_SIZE) - 1)) != HANDLE_MAGIC - || networkHandle < 0) { - throw new IllegalArgumentException( - "Value passed to fromNetworkHandle() is not a network handle."); - } - return new Network((int) (networkHandle >> HANDLE_MAGIC_SIZE)); - } - - /** - * Returns a handle representing this {@code Network}, for use with the NDK API. - */ - public long getNetworkHandle() { - // The network handle is explicitly not the same as the netId. - // - // The netId is an implementation detail which might be changed in the - // future, or which alone (i.e. in the absence of some additional - // context) might not be sufficient to fully identify a Network. - // - // As such, the intention is to prevent accidental misuse of the API - // that might result if a developer assumed that handles and netIds - // were identical and passing a netId to a call expecting a handle - // "just worked". Such accidental misuse, if widely deployed, might - // prevent future changes to the semantics of the netId field or - // inhibit the expansion of state required for Network objects. - // - // This extra layer of indirection might be seen as paranoia, and might - // never end up being necessary, but the added complexity is trivial. - // At some future date it may be desirable to realign the handle with - // Multiple Provisioning Domains API recommendations, as made by the - // IETF mif working group. - if (netId == 0) { - return 0L; // make this zero condition obvious for debugging - } - return (((long) netId) << HANDLE_MAGIC_SIZE) | HANDLE_MAGIC; - } - - // implement the Parcelable interface - public int describeContents() { - return 0; - } - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(netId); - } - - public static final @android.annotation.NonNull Creator<Network> CREATOR = - new Creator<Network>() { - public Network createFromParcel(Parcel in) { - int netId = in.readInt(); - - return new Network(netId); - } - - public Network[] newArray(int size) { - return new Network[size]; - } - }; - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Network)) return false; - Network other = (Network)obj; - return this.netId == other.netId; - } - - @Override - public int hashCode() { - return netId * 11; - } - - @Override - public String toString() { - return Integer.toString(netId); - } - - /** @hide */ - public void dumpDebug(ProtoOutputStream proto, long fieldId) { - final long token = proto.start(fieldId); - proto.write(NetworkProto.NET_ID, netId); - proto.end(token); - } -} diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java deleted file mode 100644 index d22d82d1f4d0..000000000000 --- a/core/java/android/net/NetworkAgent.java +++ /dev/null @@ -1,1185 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.IntDef; -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.compat.annotation.UnsupportedAppUsage; -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.os.ConditionVariable; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.RemoteException; -import android.telephony.data.EpsBearerQosSessionAttributes; -import android.util.Log; - -import com.android.connectivity.aidl.INetworkAgent; -import com.android.connectivity.aidl.INetworkAgentRegistry; -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.Protocol; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * A utility class for handling for communicating between bearer-specific - * code and ConnectivityService. - * - * An agent manages the life cycle of a network. A network starts its - * life cycle when {@link register} is called on NetworkAgent. The network - * is then connecting. When full L3 connectivity has been established, - * the agent should call {@link markConnected} to inform the system that - * this network is ready to use. When the network disconnects its life - * ends and the agent should call {@link unregister}, at which point the - * system will clean up and free resources. - * Any reconnection becomes a new logical network, so after a network - * is disconnected the agent cannot be used any more. Network providers - * should create a new NetworkAgent instance to handle new connections. - * - * A bearer may have more than one NetworkAgent if it can simultaneously - * support separate networks (IMS / Internet / MMS Apns on cellular, or - * perhaps connections with different SSID or P2P for Wi-Fi). - * - * This class supports methods to start and stop sending keepalive packets. - * Keepalive packets are typically sent at periodic intervals over a network - * with NAT when there is no other traffic to avoid the network forcefully - * closing the connection. NetworkAgents that manage technologies that - * have hardware support for keepalive should implement the related - * methods to save battery life. NetworkAgent that cannot get support - * without waking up the CPU should not, as this would be prohibitive in - * terms of battery - these agents should simply not override the related - * methods, which results in the implementation returning - * {@link SocketKeepalive.ERROR_UNSUPPORTED} as appropriate. - * - * Keepalive packets need to be sent at relatively frequent intervals - * (a few seconds to a few minutes). As the contents of keepalive packets - * depend on the current network status, hardware needs to be configured - * to send them and has a limited amount of memory to do so. The HAL - * formalizes this as slots that an implementation can configure to send - * the correct packets. Devices typically have a small number of slots - * per radio technology, and the specific number of slots for each - * technology is specified in configuration files. - * {@see SocketKeepalive} for details. - * - * @hide - */ -@SystemApi -public abstract class NetworkAgent { - /** - * The {@link Network} corresponding to this object. - */ - @Nullable - private volatile Network mNetwork; - - @Nullable - private volatile INetworkAgentRegistry mRegistry; - - private interface RegistryAction { - void execute(@NonNull INetworkAgentRegistry registry) throws RemoteException; - } - - private final Handler mHandler; - private final String LOG_TAG; - private static final boolean DBG = true; - private static final boolean VDBG = false; - private final ArrayList<RegistryAction> mPreConnectedQueue = new ArrayList<>(); - private volatile long mLastBwRefreshTime = 0; - private static final long BW_REFRESH_MIN_WIN_MS = 500; - private boolean mBandwidthUpdateScheduled = false; - private AtomicBoolean mBandwidthUpdatePending = new AtomicBoolean(false); - @NonNull - private NetworkInfo mNetworkInfo; - @NonNull - private final Object mRegisterLock = new Object(); - - /** - * The ID of the {@link NetworkProvider} that created this object, or - * {@link NetworkProvider#ID_NONE} if unknown. - * @hide - */ - public final int providerId; - - private static final int BASE = Protocol.BASE_NETWORK_AGENT; - - /** - * Sent by ConnectivityService to the NetworkAgent to inform it of - * suspected connectivity problems on its network. The NetworkAgent - * should take steps to verify and correct connectivity. - * @hide - */ - public static final int CMD_SUSPECT_BAD = BASE; - - /** - * Sent by the NetworkAgent (note the EVENT vs CMD prefix) to - * ConnectivityService to pass the current NetworkInfo (connection state). - * Sent when the NetworkInfo changes, mainly due to change of state. - * obj = NetworkInfo - * @hide - */ - public static final int EVENT_NETWORK_INFO_CHANGED = BASE + 1; - - /** - * Sent by the NetworkAgent to ConnectivityService to pass the current - * NetworkCapabilties. - * obj = NetworkCapabilities - * @hide - */ - public static final int EVENT_NETWORK_CAPABILITIES_CHANGED = BASE + 2; - - /** - * Sent by the NetworkAgent to ConnectivityService to pass the current - * NetworkProperties. - * obj = NetworkProperties - * @hide - */ - public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3; - - /** - * Centralize the place where base network score, and network score scaling, will be - * stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE - * @hide - */ - public static final int WIFI_BASE_SCORE = 60; - - /** - * Sent by the NetworkAgent to ConnectivityService to pass the current - * network score. - * arg1 = network score int - * @hide - */ - public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4; - - /** - * Sent by the NetworkAgent to ConnectivityService to pass the current - * list of underlying networks. - * obj = array of Network objects - * @hide - */ - public static final int EVENT_UNDERLYING_NETWORKS_CHANGED = BASE + 5; - - /** - * Sent by ConnectivityService to the NetworkAgent to inform the agent of the - * networks status - whether we could use the network or could not, due to - * either a bad network configuration (no internet link) or captive portal. - * - * arg1 = either {@code VALID_NETWORK} or {@code INVALID_NETWORK} - * obj = Bundle containing map from {@code REDIRECT_URL_KEY} to {@code String} - * representing URL that Internet probe was redirect to, if it was redirected, - * or mapping to {@code null} otherwise. - * @hide - */ - public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7; - - - /** - * Network validation suceeded. - * Corresponds to {@link NetworkCapabilities.NET_CAPABILITY_VALIDATED}. - */ - public static final int VALIDATION_STATUS_VALID = 1; - - /** - * Network validation was attempted and failed. This may be received more than once as - * subsequent validation attempts are made. - */ - public static final int VALIDATION_STATUS_NOT_VALID = 2; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "VALIDATION_STATUS_" }, value = { - VALIDATION_STATUS_VALID, - VALIDATION_STATUS_NOT_VALID - }) - public @interface ValidationStatus {} - - // TODO: remove. - /** @hide */ - public static final int VALID_NETWORK = 1; - /** @hide */ - public static final int INVALID_NETWORK = 2; - - /** - * The key for the redirect URL in the Bundle argument of {@code CMD_REPORT_NETWORK_STATUS}. - * @hide - */ - public static final String REDIRECT_URL_KEY = "redirect URL"; - - /** - * Sent by the NetworkAgent to ConnectivityService to indicate this network was - * explicitly selected. This should be sent before the NetworkInfo is marked - * CONNECTED so it can be given special treatment at that time. - * - * obj = boolean indicating whether to use this network even if unvalidated - * @hide - */ - public static final int EVENT_SET_EXPLICITLY_SELECTED = BASE + 8; - - /** - * Sent by ConnectivityService to the NetworkAgent to inform the agent of - * whether the network should in the future be used even if not validated. - * This decision is made by the user, but it is the network transport's - * responsibility to remember it. - * - * arg1 = 1 if true, 0 if false - * @hide - */ - public static final int CMD_SAVE_ACCEPT_UNVALIDATED = BASE + 9; - - /** - * Sent by ConnectivityService to the NetworkAgent to inform the agent to pull - * the underlying network connection for updated bandwidth information. - * @hide - */ - public static final int CMD_REQUEST_BANDWIDTH_UPDATE = BASE + 10; - - /** - * Sent by ConnectivityService to the NetworkAgent to request that the specified packet be sent - * periodically on the given interval. - * - * arg1 = the hardware slot number of the keepalive to start - * arg2 = interval in seconds - * obj = KeepalivePacketData object describing the data to be sent - * - * Also used internally by ConnectivityService / KeepaliveTracker, with different semantics. - * @hide - */ - public static final int CMD_START_SOCKET_KEEPALIVE = BASE + 11; - - /** - * Requests that the specified keepalive packet be stopped. - * - * arg1 = hardware slot number of the keepalive to stop. - * - * Also used internally by ConnectivityService / KeepaliveTracker, with different semantics. - * @hide - */ - public static final int CMD_STOP_SOCKET_KEEPALIVE = BASE + 12; - - /** - * Sent by the NetworkAgent to ConnectivityService to provide status on a socket keepalive - * request. This may either be the reply to a CMD_START_SOCKET_KEEPALIVE, or an asynchronous - * error notification. - * - * This is also sent by KeepaliveTracker to the app's {@link SocketKeepalive}, - * so that the app's {@link SocketKeepalive.Callback} methods can be called. - * - * arg1 = hardware slot number of the keepalive - * arg2 = error code - * @hide - */ - public static final int EVENT_SOCKET_KEEPALIVE = BASE + 13; - - /** - * Sent by ConnectivityService to inform this network transport of signal strength thresholds - * that when crossed should trigger a system wakeup and a NetworkCapabilities update. - * - * obj = int[] describing signal strength thresholds. - * @hide - */ - public static final int CMD_SET_SIGNAL_STRENGTH_THRESHOLDS = BASE + 14; - - /** - * Sent by ConnectivityService to the NeworkAgent to inform the agent to avoid - * automatically reconnecting to this network (e.g. via autojoin). Happens - * when user selects "No" option on the "Stay connected?" dialog box. - * @hide - */ - public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 15; - - /** - * Sent by the KeepaliveTracker to NetworkAgent to add a packet filter. - * - * For TCP keepalive offloads, keepalive packets are sent by the firmware. However, because the - * remote site will send ACK packets in response to the keepalive packets, the firmware also - * needs to be configured to properly filter the ACKs to prevent the system from waking up. - * This does not happen with UDP, so this message is TCP-specific. - * arg1 = hardware slot number of the keepalive to filter for. - * obj = the keepalive packet to send repeatedly. - * @hide - */ - public static final int CMD_ADD_KEEPALIVE_PACKET_FILTER = BASE + 16; - - /** - * Sent by the KeepaliveTracker to NetworkAgent to remove a packet filter. See - * {@link #CMD_ADD_KEEPALIVE_PACKET_FILTER}. - * arg1 = hardware slot number of the keepalive packet filter to remove. - * @hide - */ - public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17; - - /** - * Sent by ConnectivityService to the NetworkAgent to complete the bidirectional connection. - * obj = INetworkAgentRegistry - */ - private static final int EVENT_AGENT_CONNECTED = BASE + 18; - - /** - * Sent by ConnectivityService to the NetworkAgent to inform the agent that it was disconnected. - */ - private static final int EVENT_AGENT_DISCONNECTED = BASE + 19; - - /** - * Sent by QosCallbackTracker to {@link NetworkAgent} to register a new filter with - * callback. - * - * arg1 = QoS agent callback ID - * obj = {@link QosFilter} - * @hide - */ - public static final int CMD_REGISTER_QOS_CALLBACK = BASE + 20; - - /** - * Sent by QosCallbackTracker to {@link NetworkAgent} to unregister a callback. - * - * arg1 = QoS agent callback ID - * @hide - */ - public static final int CMD_UNREGISTER_QOS_CALLBACK = BASE + 21; - - private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) { - // The subtype can be changed with (TODO) setLegacySubtype, but it starts - // with 0 (TelephonyManager.NETWORK_TYPE_UNKNOWN) and an empty description. - final NetworkInfo ni = new NetworkInfo(config.legacyType, 0, config.legacyTypeName, ""); - ni.setIsAvailable(true); - ni.setDetailedState(NetworkInfo.DetailedState.CONNECTING, null /* reason */, - config.getLegacyExtraInfo()); - return ni; - } - - /** - * Create a new network agent. - * @param context a {@link Context} to get system services from. - * @param looper the {@link Looper} on which to invoke the callbacks. - * @param logTag the tag for logs - * @param nc the initial {@link NetworkCapabilities} of this network. Update with - * sendNetworkCapabilities. - * @param lp the initial {@link LinkProperties} of this network. Update with sendLinkProperties. - * @param score the initial score of this network. Update with sendNetworkScore. - * @param config an immutable {@link NetworkAgentConfig} for this agent. - * @param provider the {@link NetworkProvider} managing this agent. - */ - public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag, - @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, - @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) { - this(looper, context, logTag, nc, lp, score, config, - provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(), - getLegacyNetworkInfo(config)); - } - - private static class InitialConfiguration { - public final Context context; - public final NetworkCapabilities capabilities; - public final LinkProperties properties; - public final int score; - public final NetworkAgentConfig config; - public final NetworkInfo info; - InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities, - @NonNull LinkProperties properties, int score, @NonNull NetworkAgentConfig config, - @NonNull NetworkInfo info) { - this.context = context; - this.capabilities = capabilities; - this.properties = properties; - this.score = score; - this.config = config; - this.info = info; - } - } - private volatile InitialConfiguration mInitialConfiguration; - - private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag, - @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, - @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni) { - mHandler = new NetworkAgentHandler(looper); - LOG_TAG = logTag; - mNetworkInfo = new NetworkInfo(ni); - this.providerId = providerId; - if (ni == null || nc == null || lp == null) { - throw new IllegalArgumentException(); - } - - mInitialConfiguration = new InitialConfiguration(context, - new NetworkCapabilities(nc, /* parcelLocationSensitiveFields */ true), - new LinkProperties(lp), score, config, ni); - } - - private class NetworkAgentHandler extends Handler { - NetworkAgentHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_AGENT_CONNECTED: { - if (mRegistry != null) { - log("Received new connection while already connected!"); - } else { - if (VDBG) log("NetworkAgent fully connected"); - synchronized (mPreConnectedQueue) { - final INetworkAgentRegistry registry = (INetworkAgentRegistry) msg.obj; - mRegistry = registry; - for (RegistryAction a : mPreConnectedQueue) { - try { - a.execute(registry); - } catch (RemoteException e) { - Log.wtf(LOG_TAG, "Communication error with registry", e); - // Fall through - } - } - mPreConnectedQueue.clear(); - } - } - break; - } - case EVENT_AGENT_DISCONNECTED: { - if (DBG) log("NetworkAgent channel lost"); - // let the client know CS is done with us. - onNetworkUnwanted(); - synchronized (mPreConnectedQueue) { - mRegistry = null; - } - break; - } - case CMD_SUSPECT_BAD: { - log("Unhandled Message " + msg); - break; - } - case CMD_REQUEST_BANDWIDTH_UPDATE: { - long currentTimeMs = System.currentTimeMillis(); - if (VDBG) { - log("CMD_REQUEST_BANDWIDTH_UPDATE request received."); - } - if (currentTimeMs >= (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) { - mBandwidthUpdateScheduled = false; - if (!mBandwidthUpdatePending.getAndSet(true)) { - onBandwidthUpdateRequested(); - } - } else { - // deliver the request at a later time rather than discard it completely. - if (!mBandwidthUpdateScheduled) { - long waitTime = mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS - - currentTimeMs + 1; - mBandwidthUpdateScheduled = sendEmptyMessageDelayed( - CMD_REQUEST_BANDWIDTH_UPDATE, waitTime); - } - } - break; - } - case CMD_REPORT_NETWORK_STATUS: { - String redirectUrl = ((Bundle) msg.obj).getString(REDIRECT_URL_KEY); - if (VDBG) { - log("CMD_REPORT_NETWORK_STATUS(" - + (msg.arg1 == VALID_NETWORK ? "VALID, " : "INVALID, ") - + redirectUrl); - } - Uri uri = null; - try { - if (null != redirectUrl) { - uri = Uri.parse(redirectUrl); - } - } catch (Exception e) { - Log.wtf(LOG_TAG, "Surprising URI : " + redirectUrl, e); - } - onValidationStatus(msg.arg1 /* status */, uri); - break; - } - case CMD_SAVE_ACCEPT_UNVALIDATED: { - onSaveAcceptUnvalidated(msg.arg1 != 0); - break; - } - case CMD_START_SOCKET_KEEPALIVE: { - onStartSocketKeepalive(msg.arg1 /* slot */, - Duration.ofSeconds(msg.arg2) /* interval */, - (KeepalivePacketData) msg.obj /* packet */); - break; - } - case CMD_STOP_SOCKET_KEEPALIVE: { - onStopSocketKeepalive(msg.arg1 /* slot */); - break; - } - - case CMD_SET_SIGNAL_STRENGTH_THRESHOLDS: { - onSignalStrengthThresholdsUpdated((int[]) msg.obj); - break; - } - case CMD_PREVENT_AUTOMATIC_RECONNECT: { - onAutomaticReconnectDisabled(); - break; - } - case CMD_ADD_KEEPALIVE_PACKET_FILTER: { - onAddKeepalivePacketFilter(msg.arg1 /* slot */, - (KeepalivePacketData) msg.obj /* packet */); - break; - } - case CMD_REMOVE_KEEPALIVE_PACKET_FILTER: { - onRemoveKeepalivePacketFilter(msg.arg1 /* slot */); - break; - } - case CMD_REGISTER_QOS_CALLBACK: { - onQosCallbackRegistered( - msg.arg1 /* QoS callback id */, - (QosFilter) msg.obj /* QoS filter */); - break; - } - case CMD_UNREGISTER_QOS_CALLBACK: { - onQosCallbackUnregistered( - msg.arg1 /* QoS callback id */); - break; - } - } - } - } - - /** - * Register this network agent with ConnectivityService. - * - * This method can only be called once per network agent. - * - * @return the Network associated with this network agent (which can also be obtained later - * by calling getNetwork() on this agent). - * @throws IllegalStateException thrown by the system server if this network agent is - * already registered. - */ - @NonNull - public Network register() { - if (VDBG) log("Registering NetworkAgent"); - synchronized (mRegisterLock) { - if (mNetwork != null) { - throw new IllegalStateException("Agent already registered"); - } - final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context - .getSystemService(Context.CONNECTIVITY_SERVICE); - mNetwork = cm.registerNetworkAgent(new NetworkAgentBinder(mHandler), - new NetworkInfo(mInitialConfiguration.info), - mInitialConfiguration.properties, mInitialConfiguration.capabilities, - mInitialConfiguration.score, mInitialConfiguration.config, providerId); - mInitialConfiguration = null; // All this memory can now be GC'd - } - return mNetwork; - } - - private static class NetworkAgentBinder extends INetworkAgent.Stub { - private static final String LOG_TAG = NetworkAgentBinder.class.getSimpleName(); - - private final Handler mHandler; - - private NetworkAgentBinder(Handler handler) { - mHandler = handler; - } - - @Override - public void onRegistered(@NonNull INetworkAgentRegistry registry) { - mHandler.sendMessage(mHandler.obtainMessage(EVENT_AGENT_CONNECTED, registry)); - } - - @Override - public void onDisconnected() { - mHandler.sendMessage(mHandler.obtainMessage(EVENT_AGENT_DISCONNECTED)); - } - - @Override - public void onBandwidthUpdateRequested() { - mHandler.sendMessage(mHandler.obtainMessage(CMD_REQUEST_BANDWIDTH_UPDATE)); - } - - @Override - public void onValidationStatusChanged( - int validationStatus, @Nullable String captivePortalUrl) { - // TODO: consider using a parcelable as argument when the interface is structured - Bundle redirectUrlBundle = new Bundle(); - redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, captivePortalUrl); - mHandler.sendMessage(mHandler.obtainMessage(CMD_REPORT_NETWORK_STATUS, - validationStatus, 0, redirectUrlBundle)); - } - - @Override - public void onSaveAcceptUnvalidated(boolean acceptUnvalidated) { - mHandler.sendMessage(mHandler.obtainMessage(CMD_SAVE_ACCEPT_UNVALIDATED, - acceptUnvalidated ? 1 : 0, 0)); - } - - @Override - public void onStartNattSocketKeepalive(int slot, int intervalDurationMs, - @NonNull NattKeepalivePacketData packetData) { - mHandler.sendMessage(mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, - slot, intervalDurationMs, packetData)); - } - - @Override - public void onStartTcpSocketKeepalive(int slot, int intervalDurationMs, - @NonNull TcpKeepalivePacketData packetData) { - mHandler.sendMessage(mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, - slot, intervalDurationMs, packetData)); - } - - @Override - public void onStopSocketKeepalive(int slot) { - mHandler.sendMessage(mHandler.obtainMessage(CMD_STOP_SOCKET_KEEPALIVE, slot, 0)); - } - - @Override - public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) { - mHandler.sendMessage(mHandler.obtainMessage( - CMD_SET_SIGNAL_STRENGTH_THRESHOLDS, thresholds)); - } - - @Override - public void onPreventAutomaticReconnect() { - mHandler.sendMessage(mHandler.obtainMessage(CMD_PREVENT_AUTOMATIC_RECONNECT)); - } - - @Override - public void onAddNattKeepalivePacketFilter(int slot, - @NonNull NattKeepalivePacketData packetData) { - mHandler.sendMessage(mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, - slot, 0, packetData)); - } - - @Override - public void onAddTcpKeepalivePacketFilter(int slot, - @NonNull TcpKeepalivePacketData packetData) { - mHandler.sendMessage(mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, - slot, 0, packetData)); - } - - @Override - public void onRemoveKeepalivePacketFilter(int slot) { - mHandler.sendMessage(mHandler.obtainMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, - slot, 0)); - } - - @Override - public void onQosFilterCallbackRegistered(final int qosCallbackId, - final QosFilterParcelable qosFilterParcelable) { - if (qosFilterParcelable.getQosFilter() != null) { - mHandler.sendMessage( - mHandler.obtainMessage(CMD_REGISTER_QOS_CALLBACK, qosCallbackId, 0, - qosFilterParcelable.getQosFilter())); - return; - } - - Log.wtf(LOG_TAG, "onQosFilterCallbackRegistered: qos filter is null."); - } - - @Override - public void onQosCallbackUnregistered(final int qosCallbackId) { - mHandler.sendMessage(mHandler.obtainMessage( - CMD_UNREGISTER_QOS_CALLBACK, qosCallbackId, 0, null)); - } - } - - /** - * Register this network agent with a testing harness. - * - * The returned Messenger sends messages to the Handler. This allows a test to send - * this object {@code CMD_*} messages as if they came from ConnectivityService, which - * is useful for testing the behavior. - * - * @hide - */ - public INetworkAgent registerForTest(final Network network) { - log("Registering NetworkAgent for test"); - synchronized (mRegisterLock) { - mNetwork = network; - mInitialConfiguration = null; - } - return new NetworkAgentBinder(mHandler); - } - - /** - * Waits for the handler to be idle. - * This is useful for testing, and has smaller scope than an accessor to mHandler. - * TODO : move the implementation in common library with the tests - * @hide - */ - @VisibleForTesting - public boolean waitForIdle(final long timeoutMs) { - final ConditionVariable cv = new ConditionVariable(false); - mHandler.post(cv::open); - return cv.block(timeoutMs); - } - - /** - * @return The Network associated with this agent, or null if it's not registered yet. - */ - @Nullable - public Network getNetwork() { - return mNetwork; - } - - private void queueOrSendMessage(@NonNull RegistryAction action) { - synchronized (mPreConnectedQueue) { - if (mRegistry != null) { - try { - action.execute(mRegistry); - } catch (RemoteException e) { - Log.wtf(LOG_TAG, "Error executing registry action", e); - // Fall through: the channel is asynchronous and does not report errors back - } - } else { - mPreConnectedQueue.add(action); - } - } - } - - /** - * Must be called by the agent when the network's {@link LinkProperties} change. - * @param linkProperties the new LinkProperties. - */ - public final void sendLinkProperties(@NonNull LinkProperties linkProperties) { - Objects.requireNonNull(linkProperties); - final LinkProperties lp = new LinkProperties(linkProperties); - queueOrSendMessage(reg -> reg.sendLinkProperties(lp)); - } - - /** - * Must be called by the agent when the network's underlying networks change. - * - * <p>{@code networks} is one of the following: - * <ul> - * <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in - * decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular) - * networks to carry app traffic, but prefers or uses wifi more than mobile, wifi should appear - * first in the array.</li> - * <li><strong>an empty array</strong>: a zero-element array, meaning that the VPN has no - * underlying network connection, and thus, app traffic will not be sent or received.</li> - * <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's - * default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket} - * APIs mentioned above to send traffic over specific channels.</li> - * </ul> - * - * @param underlyingNetworks the new list of underlying networks. - * @see {@link VpnService.Builder#setUnderlyingNetworks(Network[])} - */ - public final void setUnderlyingNetworks(@Nullable List<Network> underlyingNetworks) { - final ArrayList<Network> underlyingArray = (underlyingNetworks != null) - ? new ArrayList<>(underlyingNetworks) : null; - queueOrSendMessage(reg -> reg.sendUnderlyingNetworks(underlyingArray)); - } - - /** - * Inform ConnectivityService that this agent has now connected. - * Call {@link #unregister} to disconnect. - */ - public void markConnected() { - mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null /* reason */, - mNetworkInfo.getExtraInfo()); - queueOrSendNetworkInfo(mNetworkInfo); - } - - /** - * Unregister this network agent. - * - * This signals the network has disconnected and ends its lifecycle. After this is called, - * the network is torn down and this agent can no longer be used. - */ - public void unregister() { - // When unregistering an agent nobody should use the extrainfo (or reason) any more. - mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null /* reason */, - null /* extraInfo */); - queueOrSendNetworkInfo(mNetworkInfo); - } - - /** - * Change the legacy subtype of this network agent. - * - * This is only for backward compatibility and should not be used by non-legacy network agents, - * or agents that did not use to set a subtype. As such, only TYPE_MOBILE type agents can use - * this and others will be thrown an exception if they try. - * - * @deprecated this is for backward compatibility only. - * @param legacySubtype the legacy subtype. - * @hide - */ - @Deprecated - public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) { - mNetworkInfo.setSubtype(legacySubtype, legacySubtypeName); - queueOrSendNetworkInfo(mNetworkInfo); - } - - /** - * Set the ExtraInfo of this network agent. - * - * This sets the ExtraInfo field inside the NetworkInfo returned by legacy public API and the - * broadcasts about the corresponding Network. - * This is only for backward compatibility and should not be used by non-legacy network agents, - * who will be thrown an exception if they try. The extra info should only be : - * <ul> - * <li>For cellular agents, the APN name.</li> - * <li>For ethernet agents, the interface name.</li> - * </ul> - * - * @deprecated this is for backward compatibility only. - * @param extraInfo the ExtraInfo. - * @hide - */ - @Deprecated - public void setLegacyExtraInfo(@Nullable final String extraInfo) { - mNetworkInfo.setExtraInfo(extraInfo); - queueOrSendNetworkInfo(mNetworkInfo); - } - - /** - * Must be called by the agent when it has a new NetworkInfo object. - * @hide TODO: expose something better. - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - public final void sendNetworkInfo(NetworkInfo networkInfo) { - queueOrSendNetworkInfo(new NetworkInfo(networkInfo)); - } - - private void queueOrSendNetworkInfo(NetworkInfo networkInfo) { - queueOrSendMessage(reg -> reg.sendNetworkInfo(networkInfo)); - } - - /** - * Must be called by the agent when the network's {@link NetworkCapabilities} change. - * @param networkCapabilities the new NetworkCapabilities. - */ - public final void sendNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) { - Objects.requireNonNull(networkCapabilities); - mBandwidthUpdatePending.set(false); - mLastBwRefreshTime = System.currentTimeMillis(); - final NetworkCapabilities nc = - new NetworkCapabilities(networkCapabilities, - /* parcelLocationSensitiveFields */ true); - queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc)); - } - - /** - * Must be called by the agent to update the score of this network. - * - * @param score the new score, between 0 and 99. - */ - public final void sendNetworkScore(@IntRange(from = 0, to = 99) int score) { - if (score < 0) { - throw new IllegalArgumentException("Score must be >= 0"); - } - queueOrSendMessage(reg -> reg.sendScore(score)); - } - - /** - * Must be called by the agent to indicate this network was manually selected by the user. - * This should be called before the NetworkInfo is marked CONNECTED so that this - * Network can be given special treatment at that time. If {@code acceptUnvalidated} is - * {@code true}, then the system will switch to this network. If it is {@code false} and the - * network cannot be validated, the system will ask the user whether to switch to this network. - * If the user confirms and selects "don't ask again", then the system will call - * {@link #saveAcceptUnvalidated} to persist the user's choice. Thus, if the transport ever - * calls this method with {@code acceptUnvalidated} set to {@code false}, it must also implement - * {@link #saveAcceptUnvalidated} to respect the user's choice. - * @hide should move to NetworkAgentConfig. - */ - public void explicitlySelected(boolean acceptUnvalidated) { - explicitlySelected(true /* explicitlySelected */, acceptUnvalidated); - } - - /** - * Must be called by the agent to indicate whether the network was manually selected by the - * user. This should be called before the network becomes connected, so it can be given - * special treatment when it does. - * - * If {@code explicitlySelected} is {@code true}, and {@code acceptUnvalidated} is {@code true}, - * then the system will switch to this network. If {@code explicitlySelected} is {@code true} - * and {@code acceptUnvalidated} is {@code false}, and the network cannot be validated, the - * system will ask the user whether to switch to this network. If the user confirms and selects - * "don't ask again", then the system will call {@link #saveAcceptUnvalidated} to persist the - * user's choice. Thus, if the transport ever calls this method with {@code explicitlySelected} - * set to {@code true} and {@code acceptUnvalidated} set to {@code false}, it must also - * implement {@link #saveAcceptUnvalidated} to respect the user's choice. - * - * If {@code explicitlySelected} is {@code false} and {@code acceptUnvalidated} is - * {@code true}, the system will interpret this as the user having accepted partial connectivity - * on this network. Thus, the system will switch to the network and consider it validated even - * if it only provides partial connectivity, but the network is not otherwise treated specially. - * @hide should move to NetworkAgentConfig. - */ - public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) { - queueOrSendMessage(reg -> reg.sendExplicitlySelected( - explicitlySelected, acceptUnvalidated)); - } - - /** - * Called when ConnectivityService has indicated they no longer want this network. - * The parent factory should (previously) have received indication of the change - * as well, either canceling NetworkRequests or altering their score such that this - * network won't be immediately requested again. - */ - public void onNetworkUnwanted() { - unwanted(); - } - /** @hide TODO delete once subclasses have moved to onNetworkUnwanted. */ - protected void unwanted() { - } - - /** - * Called when ConnectivityService request a bandwidth update. The parent factory - * shall try to overwrite this method and produce a bandwidth update if capable. - * @hide - */ - public void onBandwidthUpdateRequested() { - pollLceData(); - } - /** @hide TODO delete once subclasses have moved to onBandwidthUpdateRequested. */ - protected void pollLceData() { - } - - /** - * Called when the system determines the usefulness of this network. - * - * The system attempts to validate Internet connectivity on networks that provide the - * {@link NetworkCapabilities#NET_CAPABILITY_INTERNET} capability. - * - * Currently there are two possible values: - * {@code VALIDATION_STATUS_VALID} if Internet connectivity was validated, - * {@code VALIDATION_STATUS_NOT_VALID} if Internet connectivity was not validated. - * - * This is guaranteed to be called again when the network status changes, but the system - * may also call this multiple times even if the status does not change. - * - * @param status one of {@code VALIDATION_STATUS_VALID} or {@code VALIDATION_STATUS_NOT_VALID}. - * @param redirectUri If Internet connectivity is being redirected (e.g., on a captive portal), - * this is the destination the probes are being redirected to, otherwise {@code null}. - */ - public void onValidationStatus(@ValidationStatus int status, @Nullable Uri redirectUri) { - networkStatus(status, null == redirectUri ? "" : redirectUri.toString()); - } - /** @hide TODO delete once subclasses have moved to onValidationStatus */ - protected void networkStatus(int status, String redirectUrl) { - } - - - /** - * Called when the user asks to remember the choice to use this network even if unvalidated. - * The transport is responsible for remembering the choice, and the next time the user connects - * to the network, should explicitlySelected with {@code acceptUnvalidated} set to {@code true}. - * This method will only be called if {@link #explicitlySelected} was called with - * {@code acceptUnvalidated} set to {@code false}. - * @param accept whether the user wants to use the network even if unvalidated. - */ - public void onSaveAcceptUnvalidated(boolean accept) { - saveAcceptUnvalidated(accept); - } - /** @hide TODO delete once subclasses have moved to onSaveAcceptUnvalidated */ - protected void saveAcceptUnvalidated(boolean accept) { - } - - /** - * Requests that the network hardware send the specified packet at the specified interval. - * - * @param slot the hardware slot on which to start the keepalive. - * @param interval the interval between packets, between 10 and 3600. Note that this API - * does not support sub-second precision and will round off the request. - * @param packet the packet to send. - */ - // seconds is from SocketKeepalive.MIN_INTERVAL_SEC to MAX_INTERVAL_SEC, but these should - // not be exposed as constants because they may change in the future (API guideline 4.8) - // and should have getters if exposed at all. Getters can't be used in the annotation, - // so the values unfortunately need to be copied. - public void onStartSocketKeepalive(int slot, @NonNull Duration interval, - @NonNull KeepalivePacketData packet) { - final long intervalSeconds = interval.getSeconds(); - if (intervalSeconds < SocketKeepalive.MIN_INTERVAL_SEC - || intervalSeconds > SocketKeepalive.MAX_INTERVAL_SEC) { - throw new IllegalArgumentException("Interval needs to be comprised between " - + SocketKeepalive.MIN_INTERVAL_SEC + " and " + SocketKeepalive.MAX_INTERVAL_SEC - + " but was " + intervalSeconds); - } - final Message msg = mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, slot, - (int) intervalSeconds, packet); - startSocketKeepalive(msg); - msg.recycle(); - } - /** @hide TODO delete once subclasses have moved to onStartSocketKeepalive */ - protected void startSocketKeepalive(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); - } - - /** - * Requests that the network hardware stop a previously-started keepalive. - * - * @param slot the hardware slot on which to stop the keepalive. - */ - public void onStopSocketKeepalive(int slot) { - Message msg = mHandler.obtainMessage(CMD_STOP_SOCKET_KEEPALIVE, slot, 0, null); - stopSocketKeepalive(msg); - msg.recycle(); - } - /** @hide TODO delete once subclasses have moved to onStopSocketKeepalive */ - protected void stopSocketKeepalive(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); - } - - /** - * Must be called by the agent when a socket keepalive event occurs. - * - * @param slot the hardware slot on which the event occurred. - * @param event the event that occurred, as one of the SocketKeepalive.ERROR_* - * or SocketKeepalive.SUCCESS constants. - */ - public final void sendSocketKeepaliveEvent(int slot, - @SocketKeepalive.KeepaliveEvent int event) { - queueOrSendMessage(reg -> reg.sendSocketKeepaliveEvent(slot, event)); - } - /** @hide TODO delete once callers have moved to sendSocketKeepaliveEvent */ - public void onSocketKeepaliveEvent(int slot, int reason) { - sendSocketKeepaliveEvent(slot, reason); - } - - /** - * Called by ConnectivityService to add specific packet filter to network hardware to block - * replies (e.g., TCP ACKs) matching the sent keepalive packets. Implementations that support - * this feature must override this method. - * - * @param slot the hardware slot on which the keepalive should be sent. - * @param packet the packet that is being sent. - */ - public void onAddKeepalivePacketFilter(int slot, @NonNull KeepalivePacketData packet) { - Message msg = mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, slot, 0, packet); - addKeepalivePacketFilter(msg); - msg.recycle(); - } - /** @hide TODO delete once subclasses have moved to onAddKeepalivePacketFilter */ - protected void addKeepalivePacketFilter(Message msg) { - } - - /** - * Called by ConnectivityService to remove a packet filter installed with - * {@link #addKeepalivePacketFilter(Message)}. Implementations that support this feature - * must override this method. - * - * @param slot the hardware slot on which the keepalive is being sent. - */ - public void onRemoveKeepalivePacketFilter(int slot) { - Message msg = mHandler.obtainMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, slot, 0, null); - removeKeepalivePacketFilter(msg); - msg.recycle(); - } - /** @hide TODO delete once subclasses have moved to onRemoveKeepalivePacketFilter */ - protected void removeKeepalivePacketFilter(Message msg) { - } - - /** - * Called by ConnectivityService to inform this network agent of signal strength thresholds - * that when crossed should trigger a system wakeup and a NetworkCapabilities update. - * - * When the system updates the list of thresholds that should wake up the CPU for a - * given agent it will call this method on the agent. The agent that implement this - * should implement it in hardware so as to ensure the CPU will be woken up on breach. - * Agents are expected to react to a breach by sending an updated NetworkCapabilities - * object with the appropriate signal strength to sendNetworkCapabilities. - * - * The specific units are bearer-dependent. See details on the units and requests in - * {@link NetworkCapabilities.Builder#setSignalStrength}. - * - * @param thresholds the array of thresholds that should trigger wakeups. - */ - public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) { - setSignalStrengthThresholds(thresholds); - } - /** @hide TODO delete once subclasses have moved to onSetSignalStrengthThresholds */ - protected void setSignalStrengthThresholds(int[] thresholds) { - } - - /** - * Called when the user asks to not stay connected to this network because it was found to not - * provide Internet access. Usually followed by call to {@code unwanted}. The transport is - * responsible for making sure the device does not automatically reconnect to the same network - * after the {@code unwanted} call. - */ - public void onAutomaticReconnectDisabled() { - preventAutomaticReconnect(); - } - /** @hide TODO delete once subclasses have moved to onAutomaticReconnectDisabled */ - protected void preventAutomaticReconnect() { - } - - /** - * Called when a qos callback is registered with a filter. - * @param qosCallbackId the id for the callback registered - * @param filter the filter being registered - */ - public void onQosCallbackRegistered(final int qosCallbackId, final @NonNull QosFilter filter) { - } - - /** - * Called when a qos callback is registered with a filter. - * <p/> - * Any QoS events that are sent with the same callback id after this method is called - * are a no-op. - * - * @param qosCallbackId the id for the callback being unregistered - */ - public void onQosCallbackUnregistered(final int qosCallbackId) { - } - - - /** - * Sends the attributes of Eps Bearer Qos Session back to the Application - * - * @param qosCallbackId the callback id that the session belongs to - * @param sessionId the unique session id across all Eps Bearer Qos Sessions - * @param attributes the attributes of the Eps Qos Session - */ - public final void sendQosSessionAvailable(final int qosCallbackId, final int sessionId, - @NonNull final EpsBearerQosSessionAttributes attributes) { - Objects.requireNonNull(attributes, "The attributes must be non-null"); - queueOrSendMessage(ra -> ra.sendEpsQosSessionAvailable(qosCallbackId, - new QosSession(sessionId, QosSession.TYPE_EPS_BEARER), - attributes)); - } - - /** - * Sends event that the Eps Qos Session was lost. - * - * @param qosCallbackId the callback id that the session belongs to - * @param sessionId the unique session id across all Eps Bearer Qos Sessions - */ - public final void sendQosSessionLost(final int qosCallbackId, final int sessionId) { - queueOrSendMessage(ra -> ra.sendQosSessionLost(qosCallbackId, - new QosSession(sessionId, QosSession.TYPE_EPS_BEARER))); - } - - /** - * Sends the exception type back to the application. - * - * The NetworkAgent should not send anymore messages with this id. - * - * @param qosCallbackId the callback id this exception belongs to - * @param exceptionType the type of exception - */ - public final void sendQosCallbackError(final int qosCallbackId, - @QosCallbackException.ExceptionType final int exceptionType) { - queueOrSendMessage(ra -> ra.sendQosCallbackError(qosCallbackId, exceptionType)); - } - - - /** @hide */ - protected void log(final String s) { - Log.d(LOG_TAG, "NetworkAgent: " + s); - } -} diff --git a/core/java/android/net/NetworkAgentConfig.aidl b/core/java/android/net/NetworkAgentConfig.aidl deleted file mode 100644 index cb70bdd31260..000000000000 --- a/core/java/android/net/NetworkAgentConfig.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -parcelable NetworkAgentConfig; diff --git a/core/java/android/net/NetworkAgentConfig.java b/core/java/android/net/NetworkAgentConfig.java deleted file mode 100644 index 664c2650ff0c..000000000000 --- a/core/java/android/net/NetworkAgentConfig.java +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Objects; - -/** - * Allows a network transport to provide the system with policy and configuration information about - * a particular network when registering a {@link NetworkAgent}. This information cannot change once the agent is registered. - * - * @hide - */ -@SystemApi -public final class NetworkAgentConfig implements Parcelable { - - /** - * If the {@link Network} is a VPN, whether apps are allowed to bypass the - * VPN. This is set by a {@link VpnService} and used by - * {@link ConnectivityManager} when creating a VPN. - * - * @hide - */ - public boolean allowBypass; - - /** - * Set if the network was manually/explicitly connected to by the user either from settings - * or a 3rd party app. For example, turning on cell data is not explicit but tapping on a wifi - * ap in the wifi settings to trigger a connection is explicit. A 3rd party app asking to - * connect to a particular access point is also explicit, though this may change in the future - * as we want apps to use the multinetwork apis. - * - * @hide - */ - public boolean explicitlySelected; - - /** - * @return whether this network was explicitly selected by the user. - */ - public boolean isExplicitlySelected() { - return explicitlySelected; - } - - /** - * Set if the user desires to use this network even if it is unvalidated. This field has meaning - * only if {@link explicitlySelected} is true. If it is, this field must also be set to the - * appropriate value based on previous user choice. - * - * TODO : rename this field to match its accessor - * @hide - */ - public boolean acceptUnvalidated; - - /** - * @return whether the system should accept this network even if it doesn't validate. - */ - public boolean isUnvalidatedConnectivityAcceptable() { - return acceptUnvalidated; - } - - /** - * Whether the user explicitly set that this network should be validated even if presence of - * only partial internet connectivity. - * - * TODO : rename this field to match its accessor - * @hide - */ - public boolean acceptPartialConnectivity; - - /** - * @return whether the system should validate this network even if it only offers partial - * Internet connectivity. - */ - public boolean isPartialConnectivityAcceptable() { - return acceptPartialConnectivity; - } - - /** - * Set to avoid surfacing the "Sign in to network" notification. - * if carrier receivers/apps are registered to handle the carrier-specific provisioning - * procedure, a carrier specific provisioning notification will be placed. - * only one notification should be displayed. This field is set based on - * which notification should be used for provisioning. - * - * @hide - */ - public boolean provisioningNotificationDisabled; - - /** - * - * @return whether the sign in to network notification is enabled by this configuration. - * @hide - */ - public boolean isProvisioningNotificationEnabled() { - return !provisioningNotificationDisabled; - } - - /** - * For mobile networks, this is the subscriber ID (such as IMSI). - * - * @hide - */ - public String subscriberId; - - /** - * @return the subscriber ID, or null if none. - * @hide - */ - @SystemApi(client = MODULE_LIBRARIES) - @Nullable - public String getSubscriberId() { - return subscriberId; - } - - /** - * Set to skip 464xlat. This means the device will treat the network as IPv6-only and - * will not attempt to detect a NAT64 via RFC 7050 DNS lookups. - * - * @hide - */ - public boolean skip464xlat; - - /** - * @return whether NAT64 prefix detection is enabled. - * @hide - */ - public boolean isNat64DetectionEnabled() { - return !skip464xlat; - } - - /** - * The legacy type of this network agent, or TYPE_NONE if unset. - * @hide - */ - public int legacyType = ConnectivityManager.TYPE_NONE; - - /** - * @return the legacy type - */ - @ConnectivityManager.LegacyNetworkType - public int getLegacyType() { - return legacyType; - } - - /** - * Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network. - * Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode. - * - * This is not parceled, because it would not make sense. - * - * @hide - */ - public transient boolean hasShownBroken; - - /** - * The name of the legacy network type. It's a free-form string used in logging. - * @hide - */ - @NonNull - public String legacyTypeName = ""; - - /** - * @return the name of the legacy network type. It's a free-form string used in logging. - */ - @NonNull - public String getLegacyTypeName() { - return legacyTypeName; - } - - /** - * The legacy extra info of the agent. The extra info should only be : - * <ul> - * <li>For cellular agents, the APN name.</li> - * <li>For ethernet agents, the interface name.</li> - * </ul> - * @hide - */ - @NonNull - private String mLegacyExtraInfo = ""; - - /** - * The legacy extra info of the agent. - * @hide - */ - @NonNull - public String getLegacyExtraInfo() { - return mLegacyExtraInfo; - } - - /** @hide */ - public NetworkAgentConfig() { - } - - /** @hide */ - public NetworkAgentConfig(@Nullable NetworkAgentConfig nac) { - if (nac != null) { - allowBypass = nac.allowBypass; - explicitlySelected = nac.explicitlySelected; - acceptUnvalidated = nac.acceptUnvalidated; - acceptPartialConnectivity = nac.acceptPartialConnectivity; - subscriberId = nac.subscriberId; - provisioningNotificationDisabled = nac.provisioningNotificationDisabled; - skip464xlat = nac.skip464xlat; - legacyType = nac.legacyType; - legacyTypeName = nac.legacyTypeName; - mLegacyExtraInfo = nac.mLegacyExtraInfo; - } - } - - /** - * Builder class to facilitate constructing {@link NetworkAgentConfig} objects. - */ - public static final class Builder { - private final NetworkAgentConfig mConfig = new NetworkAgentConfig(); - - /** - * Sets whether the network was explicitly selected by the user. - * - * @return this builder, to facilitate chaining. - */ - @NonNull - public Builder setExplicitlySelected(final boolean explicitlySelected) { - mConfig.explicitlySelected = explicitlySelected; - return this; - } - - /** - * Sets whether the system should validate this network even if it is found not to offer - * Internet connectivity. - * - * @return this builder, to facilitate chaining. - */ - @NonNull - public Builder setUnvalidatedConnectivityAcceptable( - final boolean unvalidatedConnectivityAcceptable) { - mConfig.acceptUnvalidated = unvalidatedConnectivityAcceptable; - return this; - } - - /** - * Sets whether the system should validate this network even if it is found to only offer - * partial Internet connectivity. - * - * @return this builder, to facilitate chaining. - */ - @NonNull - public Builder setPartialConnectivityAcceptable( - final boolean partialConnectivityAcceptable) { - mConfig.acceptPartialConnectivity = partialConnectivityAcceptable; - return this; - } - - /** - * Sets the subscriber ID for this network. - * - * @return this builder, to facilitate chaining. - * @hide - */ - @NonNull - @SystemApi(client = MODULE_LIBRARIES) - public Builder setSubscriberId(@Nullable String subscriberId) { - mConfig.subscriberId = subscriberId; - return this; - } - - /** - * Disables active detection of NAT64 (e.g., via RFC 7050 DNS lookups). Used to save power - * and reduce idle traffic on networks that are known to be IPv6-only without a NAT64. - * - * @return this builder, to facilitate chaining. - * @hide - */ - @NonNull - public Builder disableNat64Detection() { - mConfig.skip464xlat = true; - return this; - } - - /** - * Disables the "Sign in to network" notification. Used if the network transport will - * perform its own carrier-specific provisioning procedure. - * - * @return this builder, to facilitate chaining. - * @hide - */ - @NonNull - public Builder disableProvisioningNotification() { - mConfig.provisioningNotificationDisabled = true; - return this; - } - - /** - * Sets the legacy type for this network. - * - * @param legacyType the type - * @return this builder, to facilitate chaining. - */ - @NonNull - public Builder setLegacyType(int legacyType) { - mConfig.legacyType = legacyType; - return this; - } - - /** - * Sets the name of the legacy type of the agent. It's a free-form string used in logging. - * @param legacyTypeName the name - * @return this builder, to facilitate chaining. - */ - @NonNull - public Builder setLegacyTypeName(@NonNull String legacyTypeName) { - mConfig.legacyTypeName = legacyTypeName; - return this; - } - - /** - * Sets the legacy extra info of the agent. - * @param legacyExtraInfo the legacy extra info. - * @return this builder, to facilitate chaining. - * @hide - */ - @NonNull - public Builder setLegacyExtraInfo(@NonNull String legacyExtraInfo) { - mConfig.mLegacyExtraInfo = legacyExtraInfo; - return this; - } - - /** - * Returns the constructed {@link NetworkAgentConfig} object. - */ - @NonNull - public NetworkAgentConfig build() { - return mConfig; - } - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final NetworkAgentConfig that = (NetworkAgentConfig) o; - return allowBypass == that.allowBypass - && explicitlySelected == that.explicitlySelected - && acceptUnvalidated == that.acceptUnvalidated - && acceptPartialConnectivity == that.acceptPartialConnectivity - && provisioningNotificationDisabled == that.provisioningNotificationDisabled - && skip464xlat == that.skip464xlat - && legacyType == that.legacyType - && Objects.equals(subscriberId, that.subscriberId) - && Objects.equals(legacyTypeName, that.legacyTypeName) - && Objects.equals(mLegacyExtraInfo, that.mLegacyExtraInfo); - } - - @Override - public int hashCode() { - return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated, - acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId, - skip464xlat, legacyType, legacyTypeName, mLegacyExtraInfo); - } - - @Override - public String toString() { - return "NetworkAgentConfig {" - + " allowBypass = " + allowBypass - + ", explicitlySelected = " + explicitlySelected - + ", acceptUnvalidated = " + acceptUnvalidated - + ", acceptPartialConnectivity = " + acceptPartialConnectivity - + ", provisioningNotificationDisabled = " + provisioningNotificationDisabled - + ", subscriberId = '" + subscriberId + '\'' - + ", skip464xlat = " + skip464xlat - + ", legacyType = " + legacyType - + ", hasShownBroken = " + hasShownBroken - + ", legacyTypeName = '" + legacyTypeName + '\'' - + ", legacyExtraInfo = '" + mLegacyExtraInfo + '\'' - + "}"; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeInt(allowBypass ? 1 : 0); - out.writeInt(explicitlySelected ? 1 : 0); - out.writeInt(acceptUnvalidated ? 1 : 0); - out.writeInt(acceptPartialConnectivity ? 1 : 0); - out.writeString(subscriberId); - out.writeInt(provisioningNotificationDisabled ? 1 : 0); - out.writeInt(skip464xlat ? 1 : 0); - out.writeInt(legacyType); - out.writeString(legacyTypeName); - out.writeString(mLegacyExtraInfo); - } - - public static final @NonNull Creator<NetworkAgentConfig> CREATOR = - new Creator<NetworkAgentConfig>() { - @Override - public NetworkAgentConfig createFromParcel(Parcel in) { - NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig(); - networkAgentConfig.allowBypass = in.readInt() != 0; - networkAgentConfig.explicitlySelected = in.readInt() != 0; - networkAgentConfig.acceptUnvalidated = in.readInt() != 0; - networkAgentConfig.acceptPartialConnectivity = in.readInt() != 0; - networkAgentConfig.subscriberId = in.readString(); - networkAgentConfig.provisioningNotificationDisabled = in.readInt() != 0; - networkAgentConfig.skip464xlat = in.readInt() != 0; - networkAgentConfig.legacyType = in.readInt(); - networkAgentConfig.legacyTypeName = in.readString(); - networkAgentConfig.mLegacyExtraInfo = in.readString(); - return networkAgentConfig; - } - - @Override - public NetworkAgentConfig[] newArray(int size) { - return new NetworkAgentConfig[size]; - } - }; -} diff --git a/core/java/android/net/NetworkCapabilities.aidl b/core/java/android/net/NetworkCapabilities.aidl deleted file mode 100644 index 01d328605de4..000000000000 --- a/core/java/android/net/NetworkCapabilities.aidl +++ /dev/null @@ -1,21 +0,0 @@ -/* -** -** Copyright (C) 2014 The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -package android.net; - -@JavaOnlyStableParcelable parcelable NetworkCapabilities; - diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java deleted file mode 100644 index 3843b9ab93c2..000000000000 --- a/core/java/android/net/NetworkCapabilities.java +++ /dev/null @@ -1,2517 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.compat.annotation.UnsupportedAppUsage; -import android.net.ConnectivityManager.NetworkCallback; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.Process; -import android.text.TextUtils; -import android.util.ArraySet; -import android.util.proto.ProtoOutputStream; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.ArrayUtils; -import com.android.internal.util.BitUtils; -import com.android.internal.util.Preconditions; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Arrays; -import java.util.Objects; -import java.util.Set; -import java.util.StringJoiner; - -/** - * Representation of the capabilities of an active network. Instances are - * typically obtained through - * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)} - * or {@link ConnectivityManager#getNetworkCapabilities(Network)}. - * <p> - * This replaces the old {@link ConnectivityManager#TYPE_MOBILE} method of - * network selection. Rather than indicate a need for Wi-Fi because an - * application needs high bandwidth and risk obsolescence when a new, fast - * network appears (like LTE), the application should specify it needs high - * bandwidth. Similarly if an application needs an unmetered network for a bulk - * transfer it can specify that rather than assuming all cellular based - * connections are metered and all Wi-Fi based connections are not. - */ -public final class NetworkCapabilities implements Parcelable { - private static final String TAG = "NetworkCapabilities"; - - // Set to true when private DNS is broken. - private boolean mPrivateDnsBroken; - - /** - * Uid of the app making the request. - */ - private int mRequestorUid; - - /** - * Package name of the app making the request. - */ - private String mRequestorPackageName; - - /** - * Indicates whether parceling should preserve fields that are set based on permissions of - * the process receiving the {@link NetworkCapabilities}. - */ - private final boolean mParcelLocationSensitiveFields; - - public NetworkCapabilities() { - mParcelLocationSensitiveFields = false; - clearAll(); - mNetworkCapabilities = DEFAULT_CAPABILITIES; - } - - public NetworkCapabilities(NetworkCapabilities nc) { - this(nc, false /* parcelLocationSensitiveFields */); - } - - /** - * Make a copy of NetworkCapabilities. - * - * @param nc Original NetworkCapabilities - * @param parcelLocationSensitiveFields Whether to parcel location sensitive data or not. - * @hide - */ - @SystemApi - public NetworkCapabilities( - @Nullable NetworkCapabilities nc, boolean parcelLocationSensitiveFields) { - mParcelLocationSensitiveFields = parcelLocationSensitiveFields; - if (nc != null) { - set(nc); - } - } - - /** - * Completely clears the contents of this object, removing even the capabilities that are set - * by default when the object is constructed. - * @hide - */ - public void clearAll() { - // Ensures that the internal copies maintained by the connectivity stack does not set - // this bit. - if (mParcelLocationSensitiveFields) { - throw new UnsupportedOperationException( - "Cannot clear NetworkCapabilities when parcelLocationSensitiveFields is set"); - } - mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0; - mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED; - mNetworkSpecifier = null; - mTransportInfo = null; - mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED; - mUids = null; - mAdministratorUids = new int[0]; - mOwnerUid = Process.INVALID_UID; - mSSID = null; - mPrivateDnsBroken = false; - mRequestorUid = Process.INVALID_UID; - mRequestorPackageName = null; - } - - /** - * Set all contents of this object to the contents of a NetworkCapabilities. - * - * @param nc Original NetworkCapabilities - * @hide - */ - public void set(@NonNull NetworkCapabilities nc) { - mNetworkCapabilities = nc.mNetworkCapabilities; - mTransportTypes = nc.mTransportTypes; - mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps; - mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps; - mNetworkSpecifier = nc.mNetworkSpecifier; - if (nc.getTransportInfo() != null) { - setTransportInfo(nc.getTransportInfo().makeCopy(mParcelLocationSensitiveFields)); - } else { - setTransportInfo(null); - } - mSignalStrength = nc.mSignalStrength; - setUids(nc.mUids); // Will make the defensive copy - setAdministratorUids(nc.getAdministratorUids()); - mOwnerUid = nc.mOwnerUid; - mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities; - mSSID = nc.mSSID; - mPrivateDnsBroken = nc.mPrivateDnsBroken; - mRequestorUid = nc.mRequestorUid; - mRequestorPackageName = nc.mRequestorPackageName; - } - - /** - * Represents the network's capabilities. If any are specified they will be satisfied - * by any Network that matches all of them. - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - private long mNetworkCapabilities; - - /** - * If any capabilities specified here they must not exist in the matching Network. - */ - private long mUnwantedNetworkCapabilities; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "NET_CAPABILITY_" }, value = { - NET_CAPABILITY_MMS, - NET_CAPABILITY_SUPL, - NET_CAPABILITY_DUN, - NET_CAPABILITY_FOTA, - NET_CAPABILITY_IMS, - NET_CAPABILITY_CBS, - NET_CAPABILITY_WIFI_P2P, - NET_CAPABILITY_IA, - NET_CAPABILITY_RCS, - NET_CAPABILITY_XCAP, - NET_CAPABILITY_EIMS, - NET_CAPABILITY_NOT_METERED, - NET_CAPABILITY_INTERNET, - NET_CAPABILITY_NOT_RESTRICTED, - NET_CAPABILITY_TRUSTED, - NET_CAPABILITY_NOT_VPN, - NET_CAPABILITY_VALIDATED, - NET_CAPABILITY_CAPTIVE_PORTAL, - NET_CAPABILITY_NOT_ROAMING, - NET_CAPABILITY_FOREGROUND, - NET_CAPABILITY_NOT_CONGESTED, - NET_CAPABILITY_NOT_SUSPENDED, - NET_CAPABILITY_OEM_PAID, - NET_CAPABILITY_MCX, - NET_CAPABILITY_PARTIAL_CONNECTIVITY, - NET_CAPABILITY_TEMPORARILY_NOT_METERED, - NET_CAPABILITY_OEM_PRIVATE, - NET_CAPABILITY_VEHICLE_INTERNAL, - NET_CAPABILITY_NOT_VCN_MANAGED, - }) - public @interface NetCapability { } - - /** - * Indicates this is a network that has the ability to reach the - * carrier's MMSC for sending and receiving MMS messages. - */ - public static final int NET_CAPABILITY_MMS = 0; - - /** - * Indicates this is a network that has the ability to reach the carrier's - * SUPL server, used to retrieve GPS information. - */ - public static final int NET_CAPABILITY_SUPL = 1; - - /** - * Indicates this is a network that has the ability to reach the carrier's - * DUN or tethering gateway. - */ - public static final int NET_CAPABILITY_DUN = 2; - - /** - * Indicates this is a network that has the ability to reach the carrier's - * FOTA portal, used for over the air updates. - */ - public static final int NET_CAPABILITY_FOTA = 3; - - /** - * Indicates this is a network that has the ability to reach the carrier's - * IMS servers, used for network registration and signaling. - */ - public static final int NET_CAPABILITY_IMS = 4; - - /** - * Indicates this is a network that has the ability to reach the carrier's - * CBS servers, used for carrier specific services. - */ - public static final int NET_CAPABILITY_CBS = 5; - - /** - * Indicates this is a network that has the ability to reach a Wi-Fi direct - * peer. - */ - public static final int NET_CAPABILITY_WIFI_P2P = 6; - - /** - * Indicates this is a network that has the ability to reach a carrier's - * Initial Attach servers. - */ - public static final int NET_CAPABILITY_IA = 7; - - /** - * Indicates this is a network that has the ability to reach a carrier's - * RCS servers, used for Rich Communication Services. - */ - public static final int NET_CAPABILITY_RCS = 8; - - /** - * Indicates this is a network that has the ability to reach a carrier's - * XCAP servers, used for configuration and control. - */ - public static final int NET_CAPABILITY_XCAP = 9; - - /** - * Indicates this is a network that has the ability to reach a carrier's - * Emergency IMS servers or other services, used for network signaling - * during emergency calls. - */ - public static final int NET_CAPABILITY_EIMS = 10; - - /** - * Indicates that this network is unmetered. - */ - public static final int NET_CAPABILITY_NOT_METERED = 11; - - /** - * Indicates that this network should be able to reach the internet. - */ - public static final int NET_CAPABILITY_INTERNET = 12; - - /** - * Indicates that this network is available for general use. If this is not set - * applications should not attempt to communicate on this network. Note that this - * is simply informative and not enforcement - enforcement is handled via other means. - * Set by default. - */ - public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; - - /** - * Indicates that the user has indicated implicit trust of this network. This - * generally means it's a sim-selected carrier, a plugged in ethernet, a paired - * BT device or a wifi the user asked to connect to. Untrusted networks - * are probably limited to unknown wifi AP. Set by default. - */ - public static final int NET_CAPABILITY_TRUSTED = 14; - - /** - * Indicates that this network is not a VPN. This capability is set by default and should be - * explicitly cleared for VPN networks. - */ - public static final int NET_CAPABILITY_NOT_VPN = 15; - - /** - * Indicates that connectivity on this network was successfully validated. For example, for a - * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully - * detected. - */ - public static final int NET_CAPABILITY_VALIDATED = 16; - - /** - * Indicates that this network was found to have a captive portal in place last time it was - * probed. - */ - public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; - - /** - * Indicates that this network is not roaming. - */ - public static final int NET_CAPABILITY_NOT_ROAMING = 18; - - /** - * Indicates that this network is available for use by apps, and not a network that is being - * kept up in the background to facilitate fast network switching. - */ - public static final int NET_CAPABILITY_FOREGROUND = 19; - - /** - * Indicates that this network is not congested. - * <p> - * When a network is congested, applications should defer network traffic - * that can be done at a later time, such as uploading analytics. - */ - public static final int NET_CAPABILITY_NOT_CONGESTED = 20; - - /** - * Indicates that this network is not currently suspended. - * <p> - * When a network is suspended, the network's IP addresses and any connections - * established on the network remain valid, but the network is temporarily unable - * to transfer data. This can happen, for example, if a cellular network experiences - * a temporary loss of signal, such as when driving through a tunnel, etc. - * A network with this capability is not suspended, so is expected to be able to - * transfer data. - */ - public static final int NET_CAPABILITY_NOT_SUSPENDED = 21; - - /** - * Indicates that traffic that goes through this network is paid by oem. For example, - * this network can be used by system apps to upload telemetry data. - * @hide - */ - @SystemApi - public static final int NET_CAPABILITY_OEM_PAID = 22; - - /** - * Indicates this is a network that has the ability to reach a carrier's Mission Critical - * servers. - */ - public static final int NET_CAPABILITY_MCX = 23; - - /** - * Indicates that this network was tested to only provide partial connectivity. - * @hide - */ - @SystemApi - public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; - - /** - * Indicates that this network is temporarily unmetered. - * <p> - * This capability will be set for networks that are generally metered, but are currently - * unmetered, e.g., because the user is in a particular area. This capability can be changed at - * any time. When it is removed, applications are responsible for stopping any data transfer - * that should not occur on a metered network. - * Note that most apps should use {@link #NET_CAPABILITY_NOT_METERED} instead. For more - * information, see https://developer.android.com/about/versions/11/features/5g#meteredness. - */ - public static final int NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25; - - /** - * Indicates that this network is private to the OEM and meant only for OEM use. - * @hide - */ - @SystemApi - public static final int NET_CAPABILITY_OEM_PRIVATE = 26; - - /** - * Indicates this is an internal vehicle network, meant to communicate with other - * automotive systems. - * - * @hide - */ - @SystemApi - public static final int NET_CAPABILITY_VEHICLE_INTERNAL = 27; - - /** - * Indicates that this network is not managed by a Virtual Carrier Network (VCN). - * - * TODO(b/177299683): Add additional clarifying javadoc. - * @hide - */ - public static final int NET_CAPABILITY_NOT_VCN_MANAGED = 28; - - private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; - private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_VCN_MANAGED; - - /** - * Network capabilities that are expected to be mutable, i.e., can change while a particular - * network is connected. - */ - private static final long MUTABLE_CAPABILITIES = - // TRUSTED can change when user explicitly connects to an untrusted network in Settings. - // http://b/18206275 - (1 << NET_CAPABILITY_TRUSTED) - | (1 << NET_CAPABILITY_VALIDATED) - | (1 << NET_CAPABILITY_CAPTIVE_PORTAL) - | (1 << NET_CAPABILITY_NOT_ROAMING) - | (1 << NET_CAPABILITY_FOREGROUND) - | (1 << NET_CAPABILITY_NOT_CONGESTED) - | (1 << NET_CAPABILITY_NOT_SUSPENDED) - | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY) - | (1 << NET_CAPABILITY_TEMPORARILY_NOT_METERED) - | (1 << NET_CAPABILITY_NOT_VCN_MANAGED); - - /** - * Network capabilities that are not allowed in NetworkRequests. This exists because the - * NetworkFactory / NetworkAgent model does not deal well with the situation where a - * capability's presence cannot be known in advance. If such a capability is requested, then we - * can get into a cycle where the NetworkFactory endlessly churns out NetworkAgents that then - * get immediately torn down because they do not have the requested capability. - */ - // Note that as a historical exception, the TRUSTED and NOT_VCN_MANAGED capabilities - // are mutable but requestable. Factories are responsible for not getting - // in an infinite loop about these. - private static final long NON_REQUESTABLE_CAPABILITIES = - MUTABLE_CAPABILITIES - & ~(1 << NET_CAPABILITY_TRUSTED) - & ~(1 << NET_CAPABILITY_NOT_VCN_MANAGED); - - /** - * Capabilities that are set by default when the object is constructed. - */ - private static final long DEFAULT_CAPABILITIES = - (1 << NET_CAPABILITY_NOT_RESTRICTED) - | (1 << NET_CAPABILITY_TRUSTED) - | (1 << NET_CAPABILITY_NOT_VPN); - - /** - * Capabilities that suggest that a network is restricted. - * {@see #maybeMarkCapabilitiesRestricted}, {@see #FORCE_RESTRICTED_CAPABILITIES} - */ - @VisibleForTesting - /* package */ static final long RESTRICTED_CAPABILITIES = - (1 << NET_CAPABILITY_CBS) - | (1 << NET_CAPABILITY_DUN) - | (1 << NET_CAPABILITY_EIMS) - | (1 << NET_CAPABILITY_FOTA) - | (1 << NET_CAPABILITY_IA) - | (1 << NET_CAPABILITY_IMS) - | (1 << NET_CAPABILITY_MCX) - | (1 << NET_CAPABILITY_RCS) - | (1 << NET_CAPABILITY_VEHICLE_INTERNAL) - | (1 << NET_CAPABILITY_XCAP); - - /** - * Capabilities that force network to be restricted. - * {@see #maybeMarkCapabilitiesRestricted}. - */ - private static final long FORCE_RESTRICTED_CAPABILITIES = - (1 << NET_CAPABILITY_OEM_PAID) - | (1 << NET_CAPABILITY_OEM_PRIVATE); - - /** - * Capabilities that suggest that a network is unrestricted. - * {@see #maybeMarkCapabilitiesRestricted}. - */ - @VisibleForTesting - /* package */ static final long UNRESTRICTED_CAPABILITIES = - (1 << NET_CAPABILITY_INTERNET) - | (1 << NET_CAPABILITY_MMS) - | (1 << NET_CAPABILITY_SUPL) - | (1 << NET_CAPABILITY_WIFI_P2P); - - /** - * Capabilities that are managed by ConnectivityService. - */ - private static final long CONNECTIVITY_MANAGED_CAPABILITIES = - (1 << NET_CAPABILITY_VALIDATED) - | (1 << NET_CAPABILITY_CAPTIVE_PORTAL) - | (1 << NET_CAPABILITY_FOREGROUND) - | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY); - - /** - * Capabilities that are allowed for test networks. This list must be set so that it is safe - * for an unprivileged user to create a network with these capabilities via shell. As such, - * it must never contain capabilities that are generally useful to the system, such as - * INTERNET, IMS, SUPL, etc. - */ - private static final long TEST_NETWORKS_ALLOWED_CAPABILITIES = - (1 << NET_CAPABILITY_NOT_METERED) - | (1 << NET_CAPABILITY_TEMPORARILY_NOT_METERED) - | (1 << NET_CAPABILITY_NOT_RESTRICTED) - | (1 << NET_CAPABILITY_NOT_VPN) - | (1 << NET_CAPABILITY_NOT_ROAMING) - | (1 << NET_CAPABILITY_NOT_CONGESTED) - | (1 << NET_CAPABILITY_NOT_SUSPENDED) - | (1 << NET_CAPABILITY_NOT_VCN_MANAGED); - - /** - * Adds the given capability to this {@code NetworkCapability} instance. - * Note that when searching for a network to satisfy a request, all capabilities - * requested must be satisfied. - * - * @param capability the capability to be added. - * @return This NetworkCapabilities instance, to facilitate chaining. - * @hide - */ - public @NonNull NetworkCapabilities addCapability(@NetCapability int capability) { - // If the given capability was previously added to the list of unwanted capabilities - // then the capability will also be removed from the list of unwanted capabilities. - // TODO: Consider adding unwanted capabilities to the public API and mention this - // in the documentation. - checkValidCapability(capability); - mNetworkCapabilities |= 1 << capability; - mUnwantedNetworkCapabilities &= ~(1 << capability); // remove from unwanted capability list - return this; - } - - /** - * Adds the given capability to the list of unwanted capabilities of this - * {@code NetworkCapability} instance. Note that when searching for a network to - * satisfy a request, the network must not contain any capability from unwanted capability - * list. - * <p> - * If the capability was previously added to the list of required capabilities (for - * example, it was there by default or added using {@link #addCapability(int)} method), then - * it will be removed from the list of required capabilities as well. - * - * @see #addCapability(int) - * @hide - */ - public void addUnwantedCapability(@NetCapability int capability) { - checkValidCapability(capability); - mUnwantedNetworkCapabilities |= 1 << capability; - mNetworkCapabilities &= ~(1 << capability); // remove from requested capabilities - } - - /** - * Removes (if found) the given capability from this {@code NetworkCapability} instance. - * - * @param capability the capability to be removed. - * @return This NetworkCapabilities instance, to facilitate chaining. - * @hide - */ - public @NonNull NetworkCapabilities removeCapability(@NetCapability int capability) { - // Note that this method removes capabilities that were added via addCapability(int), - // addUnwantedCapability(int) or setCapabilities(int[], int[]). - checkValidCapability(capability); - final long mask = ~(1 << capability); - mNetworkCapabilities &= mask; - mUnwantedNetworkCapabilities &= mask; - return this; - } - - /** - * Sets (or clears) the given capability on this {@link NetworkCapabilities} - * instance. - * @hide - */ - public @NonNull NetworkCapabilities setCapability(@NetCapability int capability, - boolean value) { - if (value) { - addCapability(capability); - } else { - removeCapability(capability); - } - return this; - } - - /** - * Gets all the capabilities set on this {@code NetworkCapability} instance. - * - * @return an array of capability values for this instance. - * @hide - */ - @UnsupportedAppUsage - public @NetCapability int[] getCapabilities() { - return BitUtils.unpackBits(mNetworkCapabilities); - } - - /** - * Gets all the unwanted capabilities set on this {@code NetworkCapability} instance. - * - * @return an array of unwanted capability values for this instance. - * @hide - */ - public @NetCapability int[] getUnwantedCapabilities() { - return BitUtils.unpackBits(mUnwantedNetworkCapabilities); - } - - - /** - * Sets all the capabilities set on this {@code NetworkCapability} instance. - * This overwrites any existing capabilities. - * - * @hide - */ - public void setCapabilities(@NetCapability int[] capabilities, - @NetCapability int[] unwantedCapabilities) { - mNetworkCapabilities = BitUtils.packBits(capabilities); - mUnwantedNetworkCapabilities = BitUtils.packBits(unwantedCapabilities); - } - - /** - * @deprecated use {@link #setCapabilities(int[], int[])} - * @hide - */ - @Deprecated - public void setCapabilities(@NetCapability int[] capabilities) { - setCapabilities(capabilities, new int[] {}); - } - - /** - * Tests for the presence of a capability on this instance. - * - * @param capability the capabilities to be tested for. - * @return {@code true} if set on this instance. - */ - public boolean hasCapability(@NetCapability int capability) { - return isValidCapability(capability) - && ((mNetworkCapabilities & (1 << capability)) != 0); - } - - /** @hide */ - public boolean hasUnwantedCapability(@NetCapability int capability) { - return isValidCapability(capability) - && ((mUnwantedNetworkCapabilities & (1 << capability)) != 0); - } - - /** - * Check if this NetworkCapabilities has system managed capabilities or not. - * @hide - */ - public boolean hasConnectivityManagedCapability() { - return ((mNetworkCapabilities & CONNECTIVITY_MANAGED_CAPABILITIES) != 0); - } - - /** Note this method may result in having the same capability in wanted and unwanted lists. */ - private void combineNetCapabilities(@NonNull NetworkCapabilities nc) { - this.mNetworkCapabilities |= nc.mNetworkCapabilities; - this.mUnwantedNetworkCapabilities |= nc.mUnwantedNetworkCapabilities; - } - - /** - * Convenience function that returns a human-readable description of the first mutable - * capability we find. Used to present an error message to apps that request mutable - * capabilities. - * - * @hide - */ - public @Nullable String describeFirstNonRequestableCapability() { - final long nonRequestable = (mNetworkCapabilities | mUnwantedNetworkCapabilities) - & NON_REQUESTABLE_CAPABILITIES; - - if (nonRequestable != 0) { - return capabilityNameOf(BitUtils.unpackBits(nonRequestable)[0]); - } - if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth"; - if (hasSignalStrength()) return "signalStrength"; - if (isPrivateDnsBroken()) { - return "privateDnsBroken"; - } - return null; - } - - private boolean satisfiedByNetCapabilities(@NonNull NetworkCapabilities nc, - boolean onlyImmutable) { - long requestedCapabilities = mNetworkCapabilities; - long requestedUnwantedCapabilities = mUnwantedNetworkCapabilities; - long providedCapabilities = nc.mNetworkCapabilities; - - if (onlyImmutable) { - requestedCapabilities &= ~MUTABLE_CAPABILITIES; - requestedUnwantedCapabilities &= ~MUTABLE_CAPABILITIES; - } - return ((providedCapabilities & requestedCapabilities) == requestedCapabilities) - && ((requestedUnwantedCapabilities & providedCapabilities) == 0); - } - - /** @hide */ - public boolean equalsNetCapabilities(@NonNull NetworkCapabilities nc) { - return (nc.mNetworkCapabilities == this.mNetworkCapabilities) - && (nc.mUnwantedNetworkCapabilities == this.mUnwantedNetworkCapabilities); - } - - private boolean equalsNetCapabilitiesRequestable(@NonNull NetworkCapabilities that) { - return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) == - (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)) - && ((this.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) == - (that.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)); - } - - /** - * Deduces that all the capabilities it provides are typically provided by restricted networks - * or not. - * - * @return {@code true} if the network should be restricted. - * @hide - */ - public boolean deduceRestrictedCapability() { - // Check if we have any capability that forces the network to be restricted. - final boolean forceRestrictedCapability = - (mNetworkCapabilities & FORCE_RESTRICTED_CAPABILITIES) != 0; - - // Verify there aren't any unrestricted capabilities. If there are we say - // the whole thing is unrestricted unless it is forced to be restricted. - final boolean hasUnrestrictedCapabilities = - (mNetworkCapabilities & UNRESTRICTED_CAPABILITIES) != 0; - - // Must have at least some restricted capabilities. - final boolean hasRestrictedCapabilities = - (mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0; - - return forceRestrictedCapability - || (hasRestrictedCapabilities && !hasUnrestrictedCapabilities); - } - - /** - * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if deducing the network is restricted. - * - * @hide - */ - public void maybeMarkCapabilitiesRestricted() { - if (deduceRestrictedCapability()) { - removeCapability(NET_CAPABILITY_NOT_RESTRICTED); - } - } - - /** - * Test networks have strong restrictions on what capabilities they can have. Enforce these - * restrictions. - * @hide - */ - public void restrictCapabilitesForTestNetwork(int creatorUid) { - final long originalCapabilities = mNetworkCapabilities; - final long originalTransportTypes = mTransportTypes; - final NetworkSpecifier originalSpecifier = mNetworkSpecifier; - final int originalSignalStrength = mSignalStrength; - final int originalOwnerUid = getOwnerUid(); - final int[] originalAdministratorUids = getAdministratorUids(); - clearAll(); - mTransportTypes = (originalTransportTypes & TEST_NETWORKS_ALLOWED_TRANSPORTS) - | (1 << TRANSPORT_TEST); - mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES; - mNetworkSpecifier = originalSpecifier; - mSignalStrength = originalSignalStrength; - - // Only retain the owner and administrator UIDs if they match the app registering the remote - // caller that registered the network. - if (originalOwnerUid == creatorUid) { - setOwnerUid(creatorUid); - } - if (ArrayUtils.contains(originalAdministratorUids, creatorUid)) { - setAdministratorUids(new int[] {creatorUid}); - } - // There is no need to clear the UIDs, they have already been cleared by clearAll() above. - } - - /** - * Representing the transport type. Apps should generally not care about transport. A - * request for a fast internet connection could be satisfied by a number of different - * transports. If any are specified here it will be satisfied a Network that matches - * any of them. If a caller doesn't care about the transport it should not specify any. - */ - private long mTransportTypes; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "TRANSPORT_" }, value = { - TRANSPORT_CELLULAR, - TRANSPORT_WIFI, - TRANSPORT_BLUETOOTH, - TRANSPORT_ETHERNET, - TRANSPORT_VPN, - TRANSPORT_WIFI_AWARE, - TRANSPORT_LOWPAN, - TRANSPORT_TEST, - }) - public @interface Transport { } - - /** - * Indicates this network uses a Cellular transport. - */ - public static final int TRANSPORT_CELLULAR = 0; - - /** - * Indicates this network uses a Wi-Fi transport. - */ - public static final int TRANSPORT_WIFI = 1; - - /** - * Indicates this network uses a Bluetooth transport. - */ - public static final int TRANSPORT_BLUETOOTH = 2; - - /** - * Indicates this network uses an Ethernet transport. - */ - public static final int TRANSPORT_ETHERNET = 3; - - /** - * Indicates this network uses a VPN transport. - */ - public static final int TRANSPORT_VPN = 4; - - /** - * Indicates this network uses a Wi-Fi Aware transport. - */ - public static final int TRANSPORT_WIFI_AWARE = 5; - - /** - * Indicates this network uses a LoWPAN transport. - */ - public static final int TRANSPORT_LOWPAN = 6; - - /** - * Indicates this network uses a Test-only virtual interface as a transport. - * - * @hide - */ - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public static final int TRANSPORT_TEST = 7; - - /** @hide */ - public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR; - /** @hide */ - public static final int MAX_TRANSPORT = TRANSPORT_TEST; - - /** @hide */ - public static boolean isValidTransport(@Transport int transportType) { - return (MIN_TRANSPORT <= transportType) && (transportType <= MAX_TRANSPORT); - } - - private static final String[] TRANSPORT_NAMES = { - "CELLULAR", - "WIFI", - "BLUETOOTH", - "ETHERNET", - "VPN", - "WIFI_AWARE", - "LOWPAN", - "TEST" - }; - - /** - * Allowed transports on a test network, in addition to TRANSPORT_TEST. - */ - private static final int TEST_NETWORKS_ALLOWED_TRANSPORTS = 1 << TRANSPORT_TEST - // Test ethernet networks can be created with EthernetManager#setIncludeTestInterfaces - | 1 << TRANSPORT_ETHERNET - // Test VPN networks can be created but their UID ranges must be empty. - | 1 << TRANSPORT_VPN; - - /** - * Adds the given transport type to this {@code NetworkCapability} instance. - * Multiple transports may be applied. Note that when searching - * for a network to satisfy a request, any listed in the request will satisfy the request. - * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a - * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network - * to be selected. This is logically different than - * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above. - * - * @param transportType the transport type to be added. - * @return This NetworkCapabilities instance, to facilitate chaining. - * @hide - */ - public @NonNull NetworkCapabilities addTransportType(@Transport int transportType) { - checkValidTransportType(transportType); - mTransportTypes |= 1 << transportType; - setNetworkSpecifier(mNetworkSpecifier); // used for exception checking - return this; - } - - /** - * Removes (if found) the given transport from this {@code NetworkCapability} instance. - * - * @param transportType the transport type to be removed. - * @return This NetworkCapabilities instance, to facilitate chaining. - * @hide - */ - public @NonNull NetworkCapabilities removeTransportType(@Transport int transportType) { - checkValidTransportType(transportType); - mTransportTypes &= ~(1 << transportType); - setNetworkSpecifier(mNetworkSpecifier); // used for exception checking - return this; - } - - /** - * Sets (or clears) the given transport on this {@link NetworkCapabilities} - * instance. - * - * @hide - */ - public @NonNull NetworkCapabilities setTransportType(@Transport int transportType, - boolean value) { - if (value) { - addTransportType(transportType); - } else { - removeTransportType(transportType); - } - return this; - } - - /** - * Gets all the transports set on this {@code NetworkCapability} instance. - * - * @return an array of transport type values for this instance. - * @hide - */ - @SystemApi - @NonNull public @Transport int[] getTransportTypes() { - return BitUtils.unpackBits(mTransportTypes); - } - - /** - * Sets all the transports set on this {@code NetworkCapability} instance. - * This overwrites any existing transports. - * - * @hide - */ - public void setTransportTypes(@Transport int[] transportTypes) { - mTransportTypes = BitUtils.packBits(transportTypes); - } - - /** - * Tests for the presence of a transport on this instance. - * - * @param transportType the transport type to be tested for. - * @return {@code true} if set on this instance. - */ - public boolean hasTransport(@Transport int transportType) { - return isValidTransport(transportType) && ((mTransportTypes & (1 << transportType)) != 0); - } - - private void combineTransportTypes(NetworkCapabilities nc) { - this.mTransportTypes |= nc.mTransportTypes; - } - - private boolean satisfiedByTransportTypes(NetworkCapabilities nc) { - return ((this.mTransportTypes == 0) - || ((this.mTransportTypes & nc.mTransportTypes) != 0)); - } - - /** @hide */ - public boolean equalsTransportTypes(NetworkCapabilities nc) { - return (nc.mTransportTypes == this.mTransportTypes); - } - - /** - * UID of the app that owns this network, or Process#INVALID_UID if none/unknown. - * - * <p>This field keeps track of the UID of the app that created this network and is in charge of - * its lifecycle. This could be the UID of apps such as the Wifi network suggestor, the running - * VPN, or Carrier Service app managing a cellular data connection. - * - * <p>For NetworkCapability instances being sent from ConnectivityService, this value MUST be - * reset to Process.INVALID_UID unless all the following conditions are met: - * - * <p>The caller is the network owner, AND one of the following sets of requirements is met: - * - * <ol> - * <li>The described Network is a VPN - * </ol> - * - * <p>OR: - * - * <ol> - * <li>The calling app is the network owner - * <li>The calling app has the ACCESS_FINE_LOCATION permission granted - * <li>The user's location toggle is on - * </ol> - * - * This is because the owner UID is location-sensitive. The apps that request a network could - * know where the device is if they can tell for sure the system has connected to the network - * they requested. - * - * <p>This is populated by the network agents and for the NetworkCapabilities instance sent by - * an app to the System Server, the value MUST be reset to Process.INVALID_UID by the system - * server. - */ - private int mOwnerUid = Process.INVALID_UID; - - /** - * Set the UID of the owner app. - * @hide - */ - public @NonNull NetworkCapabilities setOwnerUid(final int uid) { - mOwnerUid = uid; - return this; - } - - /** - * Retrieves the UID of the app that owns this network. - * - * <p>For user privacy reasons, this field will only be populated if the following conditions - * are met: - * - * <p>The caller is the network owner, AND one of the following sets of requirements is met: - * - * <ol> - * <li>The described Network is a VPN - * </ol> - * - * <p>OR: - * - * <ol> - * <li>The calling app is the network owner - * <li>The calling app has the ACCESS_FINE_LOCATION permission granted - * <li>The user's location toggle is on - * </ol> - * - * Instances of NetworkCapabilities sent to apps without the appropriate permissions will have - * this field cleared out. - */ - public int getOwnerUid() { - return mOwnerUid; - } - - private boolean equalsOwnerUid(@NonNull final NetworkCapabilities nc) { - return mOwnerUid == nc.mOwnerUid; - } - - /** - * UIDs of packages that are administrators of this network, or empty if none. - * - * <p>This field tracks the UIDs of packages that have permission to manage this network. - * - * <p>Network owners will also be listed as administrators. - * - * <p>For NetworkCapability instances being sent from the System Server, this value MUST be - * empty unless the destination is 1) the System Server, or 2) Telephony. In either case, the - * receiving entity must have the ACCESS_FINE_LOCATION permission and target R+. - * - * <p>When received from an app in a NetworkRequest this is always cleared out by the system - * server. This field is never used for matching NetworkRequests to NetworkAgents. - */ - @NonNull private int[] mAdministratorUids = new int[0]; - - /** - * Sets the int[] of UIDs that are administrators of this network. - * - * <p>UIDs included in administratorUids gain administrator privileges over this Network. - * Examples of UIDs that should be included in administratorUids are: - * - * <ul> - * <li>Carrier apps with privileges for the relevant subscription - * <li>Active VPN apps - * <li>Other application groups with a particular Network-related role - * </ul> - * - * <p>In general, user-supplied networks (such as WiFi networks) do not have an administrator. - * - * <p>An app is granted owner privileges over Networks that it supplies. The owner UID MUST - * always be included in administratorUids. - * - * <p>The administrator UIDs are set by network agents. - * - * @param administratorUids the UIDs to be set as administrators of this Network. - * @throws IllegalArgumentException if duplicate UIDs are contained in administratorUids - * @see #mAdministratorUids - * @hide - */ - @NonNull - public NetworkCapabilities setAdministratorUids(@NonNull final int[] administratorUids) { - mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length); - Arrays.sort(mAdministratorUids); - for (int i = 0; i < mAdministratorUids.length - 1; i++) { - if (mAdministratorUids[i] >= mAdministratorUids[i + 1]) { - throw new IllegalArgumentException("All administrator UIDs must be unique"); - } - } - return this; - } - - /** - * Retrieves the UIDs that are administrators of this Network. - * - * <p>This is only populated in NetworkCapabilities objects that come from network agents for - * networks that are managed by specific apps on the system, such as carrier privileged apps or - * wifi suggestion apps. This will include the network owner. - * - * @return the int[] of UIDs that are administrators of this Network - * @see #mAdministratorUids - * @hide - */ - @NonNull - @SystemApi - public int[] getAdministratorUids() { - return Arrays.copyOf(mAdministratorUids, mAdministratorUids.length); - } - - /** - * Tests if the set of administrator UIDs of this network is the same as that of the passed one. - * - * <p>The administrator UIDs must be in sorted order. - * - * <p>nc is assumed non-null. Else, NPE. - * - * @hide - */ - @VisibleForTesting(visibility = PRIVATE) - public boolean equalsAdministratorUids(@NonNull final NetworkCapabilities nc) { - return Arrays.equals(mAdministratorUids, nc.mAdministratorUids); - } - - /** - * Combine the administrator UIDs of the capabilities. - * - * <p>This is only legal if either of the administrators lists are empty, or if they are equal. - * Combining administrator UIDs is only possible for combining non-overlapping sets of UIDs. - * - * <p>If both administrator lists are non-empty but not equal, they conflict with each other. In - * this case, it would not make sense to add them together. - */ - private void combineAdministratorUids(@NonNull final NetworkCapabilities nc) { - if (nc.mAdministratorUids.length == 0) return; - if (mAdministratorUids.length == 0) { - mAdministratorUids = Arrays.copyOf(nc.mAdministratorUids, nc.mAdministratorUids.length); - return; - } - if (!equalsAdministratorUids(nc)) { - throw new IllegalStateException("Can't combine two different administrator UID lists"); - } - } - - /** - * Value indicating that link bandwidth is unspecified. - * @hide - */ - public static final int LINK_BANDWIDTH_UNSPECIFIED = 0; - - /** - * Passive link bandwidth. This is a rough guide of the expected peak bandwidth - * for the first hop on the given transport. It is not measured, but may take into account - * link parameters (Radio technology, allocated channels, etc). - */ - private int mLinkUpBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED; - private int mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED; - - /** - * Sets the upstream bandwidth for this network in Kbps. This always only refers to - * the estimated first hop transport bandwidth. - * <p> - * {@see Builder#setLinkUpstreamBandwidthKbps} - * - * @param upKbps the estimated first hop upstream (device to network) bandwidth. - * @hide - */ - public @NonNull NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) { - mLinkUpBandwidthKbps = upKbps; - return this; - } - - /** - * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to - * the estimated first hop transport bandwidth. - * - * @return The estimated first hop upstream (device to network) bandwidth. - */ - public int getLinkUpstreamBandwidthKbps() { - return mLinkUpBandwidthKbps; - } - - /** - * Sets the downstream bandwidth for this network in Kbps. This always only refers to - * the estimated first hop transport bandwidth. - * <p> - * {@see Builder#setLinkUpstreamBandwidthKbps} - * - * @param downKbps the estimated first hop downstream (network to device) bandwidth. - * @hide - */ - public @NonNull NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) { - mLinkDownBandwidthKbps = downKbps; - return this; - } - - /** - * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to - * the estimated first hop transport bandwidth. - * - * @return The estimated first hop downstream (network to device) bandwidth. - */ - public int getLinkDownstreamBandwidthKbps() { - return mLinkDownBandwidthKbps; - } - - private void combineLinkBandwidths(NetworkCapabilities nc) { - this.mLinkUpBandwidthKbps = - Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps); - this.mLinkDownBandwidthKbps = - Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps); - } - private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) { - return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps - || this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps); - } - private boolean equalsLinkBandwidths(NetworkCapabilities nc) { - return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps - && this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps); - } - /** @hide */ - public static int minBandwidth(int a, int b) { - if (a == LINK_BANDWIDTH_UNSPECIFIED) { - return b; - } else if (b == LINK_BANDWIDTH_UNSPECIFIED) { - return a; - } else { - return Math.min(a, b); - } - } - /** @hide */ - public static int maxBandwidth(int a, int b) { - return Math.max(a, b); - } - - private NetworkSpecifier mNetworkSpecifier = null; - private TransportInfo mTransportInfo = null; - - /** - * Sets the optional bearer specific network specifier. - * This has no meaning if a single transport is also not specified, so calling - * this without a single transport set will generate an exception, as will - * subsequently adding or removing transports after this is set. - * </p> - * - * @param networkSpecifier A concrete, parcelable framework class that extends - * NetworkSpecifier. - * @return This NetworkCapabilities instance, to facilitate chaining. - * @hide - */ - public @NonNull NetworkCapabilities setNetworkSpecifier( - @NonNull NetworkSpecifier networkSpecifier) { - if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) { - throw new IllegalStateException("Must have a single transport specified to use " + - "setNetworkSpecifier"); - } - - mNetworkSpecifier = networkSpecifier; - - return this; - } - - /** - * Sets the optional transport specific information. - * - * @param transportInfo A concrete, parcelable framework class that extends - * {@link TransportInfo}. - * @return This NetworkCapabilities instance, to facilitate chaining. - * @hide - */ - public @NonNull NetworkCapabilities setTransportInfo(@NonNull TransportInfo transportInfo) { - mTransportInfo = transportInfo; - return this; - } - - /** - * Gets the optional bearer specific network specifier. May be {@code null} if not set. - * - * @return The optional {@link NetworkSpecifier} specifying the bearer specific network - * specifier or {@code null}. - */ - public @Nullable NetworkSpecifier getNetworkSpecifier() { - return mNetworkSpecifier; - } - - /** - * Returns a transport-specific information container. The application may cast this - * container to a concrete sub-class based on its knowledge of the network request. The - * application should be able to deal with a {@code null} return value or an invalid case, - * e.g. use {@code instanceof} operator to verify expected type. - * - * @return A concrete implementation of the {@link TransportInfo} class or null if not - * available for the network. - */ - @Nullable public TransportInfo getTransportInfo() { - return mTransportInfo; - } - - private void combineSpecifiers(NetworkCapabilities nc) { - if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) { - throw new IllegalStateException("Can't combine two networkSpecifiers"); - } - setNetworkSpecifier(nc.mNetworkSpecifier); - } - - private boolean satisfiedBySpecifier(NetworkCapabilities nc) { - return mNetworkSpecifier == null || mNetworkSpecifier.canBeSatisfiedBy(nc.mNetworkSpecifier) - || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier; - } - - private boolean equalsSpecifier(NetworkCapabilities nc) { - return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier); - } - - private void combineTransportInfos(NetworkCapabilities nc) { - if (mTransportInfo != null && !mTransportInfo.equals(nc.mTransportInfo)) { - throw new IllegalStateException("Can't combine two TransportInfos"); - } - setTransportInfo(nc.mTransportInfo); - } - - private boolean equalsTransportInfo(NetworkCapabilities nc) { - return Objects.equals(mTransportInfo, nc.mTransportInfo); - } - - /** - * Magic value that indicates no signal strength provided. A request specifying this value is - * always satisfied. - */ - public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE; - - /** - * Signal strength. This is a signed integer, and higher values indicate better signal. - * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI. - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - private int mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED; - - /** - * Sets the signal strength. This is a signed integer, with higher values indicating a stronger - * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units - * reported by wifi code. - * <p> - * Note that when used to register a network callback, this specifies the minimum acceptable - * signal strength. When received as the state of an existing network it specifies the current - * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no - * effect when requesting a callback. - * - * @param signalStrength the bearer-specific signal strength. - * @hide - */ - public @NonNull NetworkCapabilities setSignalStrength(int signalStrength) { - mSignalStrength = signalStrength; - return this; - } - - /** - * Returns {@code true} if this object specifies a signal strength. - * - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public boolean hasSignalStrength() { - return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED; - } - - /** - * Retrieves the signal strength. - * - * @return The bearer-specific signal strength. - */ - public int getSignalStrength() { - return mSignalStrength; - } - - private void combineSignalStrength(NetworkCapabilities nc) { - this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength); - } - - private boolean satisfiedBySignalStrength(NetworkCapabilities nc) { - return this.mSignalStrength <= nc.mSignalStrength; - } - - private boolean equalsSignalStrength(NetworkCapabilities nc) { - return this.mSignalStrength == nc.mSignalStrength; - } - - /** - * List of UIDs this network applies to. No restriction if null. - * <p> - * For networks, mUids represent the list of network this applies to, and null means this - * network applies to all UIDs. - * For requests, mUids is the list of UIDs this network MUST apply to to match ; ALL UIDs - * must be included in a network so that they match. As an exception to the general rule, - * a null mUids field for requests mean "no requirements" rather than what the general rule - * would suggest ("must apply to all UIDs") : this is because this has shown to be what users - * of this API expect in practice. A network that must match all UIDs can still be - * expressed with a set ranging the entire set of possible UIDs. - * <p> - * mUids is typically (and at this time, only) used by VPN. This network is only available to - * the UIDs in this list, and it is their default network. Apps in this list that wish to - * bypass the VPN can do so iff the VPN app allows them to or if they are privileged. If this - * member is null, then the network is not restricted by app UID. If it's an empty list, then - * it means nobody can use it. - * As a special exception, the app managing this network (as identified by its UID stored in - * mOwnerUid) can always see this network. This is embodied by a special check in - * satisfiedByUids. That still does not mean the network necessarily <strong>applies</strong> - * to the app that manages it as determined by #appliesToUid. - * <p> - * Please note that in principle a single app can be associated with multiple UIDs because - * each app will have a different UID when it's run as a different (macro-)user. A single - * macro user can only have a single active VPN app at any given time however. - * <p> - * Also please be aware this class does not try to enforce any normalization on this. Callers - * can only alter the UIDs by setting them wholesale : this class does not provide any utility - * to add or remove individual UIDs or ranges. If callers have any normalization needs on - * their own (like requiring sortedness or no overlap) they need to enforce it - * themselves. Some of the internal methods also assume this is normalized as in no adjacent - * or overlapping ranges are present. - * - * @hide - */ - private ArraySet<UidRange> mUids = null; - - /** - * Convenience method to set the UIDs this network applies to to a single UID. - * @hide - */ - public @NonNull NetworkCapabilities setSingleUid(int uid) { - final ArraySet<UidRange> identity = new ArraySet<>(1); - identity.add(new UidRange(uid, uid)); - setUids(identity); - return this; - } - - /** - * Set the list of UIDs this network applies to. - * This makes a copy of the set so that callers can't modify it after the call. - * @hide - */ - public @NonNull NetworkCapabilities setUids(Set<UidRange> uids) { - if (null == uids) { - mUids = null; - } else { - mUids = new ArraySet<>(uids); - } - return this; - } - - /** - * Get the list of UIDs this network applies to. - * This returns a copy of the set so that callers can't modify the original object. - * @hide - */ - public @Nullable Set<UidRange> getUids() { - return null == mUids ? null : new ArraySet<>(mUids); - } - - /** - * Test whether this network applies to this UID. - * @hide - */ - public boolean appliesToUid(int uid) { - if (null == mUids) return true; - for (UidRange range : mUids) { - if (range.contains(uid)) { - return true; - } - } - return false; - } - - /** - * Tests if the set of UIDs that this network applies to is the same as the passed network. - * <p> - * This test only checks whether equal range objects are in both sets. It will - * return false if the ranges are not exactly the same, even if the covered UIDs - * are for an equivalent result. - * <p> - * Note that this method is not very optimized, which is fine as long as it's not used very - * often. - * <p> - * nc is assumed nonnull. - * - * @hide - */ - @VisibleForTesting - public boolean equalsUids(@NonNull NetworkCapabilities nc) { - Set<UidRange> comparedUids = nc.mUids; - if (null == comparedUids) return null == mUids; - if (null == mUids) return false; - // Make a copy so it can be mutated to check that all ranges in mUids - // also are in uids. - final Set<UidRange> uids = new ArraySet<>(mUids); - for (UidRange range : comparedUids) { - if (!uids.contains(range)) { - return false; - } - uids.remove(range); - } - return uids.isEmpty(); - } - - /** - * Test whether the passed NetworkCapabilities satisfies the UIDs this capabilities require. - * - * This method is called on the NetworkCapabilities embedded in a request with the - * capabilities of an available network. It checks whether all the UIDs from this listen - * (representing the UIDs that must have access to the network) are satisfied by the UIDs - * in the passed nc (representing the UIDs that this network is available to). - * <p> - * As a special exception, the UID that created the passed network (as represented by its - * mOwnerUid field) always satisfies a NetworkRequest requiring it (of LISTEN - * or REQUEST types alike), even if the network does not apply to it. That is so a VPN app - * can see its own network when it listens for it. - * <p> - * nc is assumed nonnull. Else, NPE. - * @see #appliesToUid - * @hide - */ - public boolean satisfiedByUids(@NonNull NetworkCapabilities nc) { - if (null == nc.mUids || null == mUids) return true; // The network satisfies everything. - for (UidRange requiredRange : mUids) { - if (requiredRange.contains(nc.mOwnerUid)) return true; - if (!nc.appliesToUidRange(requiredRange)) { - return false; - } - } - return true; - } - - /** - * Returns whether this network applies to the passed ranges. - * This assumes that to apply, the passed range has to be entirely contained - * within one of the ranges this network applies to. If the ranges are not normalized, - * this method may return false even though all required UIDs are covered because no - * single range contained them all. - * @hide - */ - @VisibleForTesting - public boolean appliesToUidRange(@Nullable UidRange requiredRange) { - if (null == mUids) return true; - for (UidRange uidRange : mUids) { - if (uidRange.containsRange(requiredRange)) { - return true; - } - } - return false; - } - - /** - * Combine the UIDs this network currently applies to with the UIDs the passed - * NetworkCapabilities apply to. - * nc is assumed nonnull. - */ - private void combineUids(@NonNull NetworkCapabilities nc) { - if (null == nc.mUids || null == mUids) { - mUids = null; - return; - } - mUids.addAll(nc.mUids); - } - - - /** - * The SSID of the network, or null if not applicable or unknown. - * <p> - * This is filled in by wifi code. - * @hide - */ - private String mSSID; - - /** - * Sets the SSID of this network. - * @hide - */ - public @NonNull NetworkCapabilities setSSID(@Nullable String ssid) { - mSSID = ssid; - return this; - } - - /** - * Gets the SSID of this network, or null if none or unknown. - * @hide - */ - @SystemApi - public @Nullable String getSsid() { - return mSSID; - } - - /** - * Tests if the SSID of this network is the same as the SSID of the passed network. - * @hide - */ - public boolean equalsSSID(@NonNull NetworkCapabilities nc) { - return Objects.equals(mSSID, nc.mSSID); - } - - /** - * Check if the SSID requirements of this object are matched by the passed object. - * @hide - */ - public boolean satisfiedBySSID(@NonNull NetworkCapabilities nc) { - return mSSID == null || mSSID.equals(nc.mSSID); - } - - /** - * Combine SSIDs of the capabilities. - * <p> - * This is only legal if either the SSID of this object is null, or both SSIDs are - * equal. - * @hide - */ - private void combineSSIDs(@NonNull NetworkCapabilities nc) { - if (mSSID != null && !mSSID.equals(nc.mSSID)) { - throw new IllegalStateException("Can't combine two SSIDs"); - } - setSSID(nc.mSSID); - } - - /** - * Combine a set of Capabilities to this one. Useful for coming up with the complete set. - * <p> - * Note that this method may break an invariant of having a particular capability in either - * wanted or unwanted lists but never in both. Requests that have the same capability in - * both lists will never be satisfied. - * @hide - */ - public void combineCapabilities(@NonNull NetworkCapabilities nc) { - combineNetCapabilities(nc); - combineTransportTypes(nc); - combineLinkBandwidths(nc); - combineSpecifiers(nc); - combineTransportInfos(nc); - combineSignalStrength(nc); - combineUids(nc); - combineSSIDs(nc); - combineRequestor(nc); - combineAdministratorUids(nc); - } - - /** - * Check if our requirements are satisfied by the given {@code NetworkCapabilities}. - * - * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. - * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link - * bandwidth, signal strength, or validation / captive portal status. - * - * @hide - */ - private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) { - return (nc != null - && satisfiedByNetCapabilities(nc, onlyImmutable) - && satisfiedByTransportTypes(nc) - && (onlyImmutable || satisfiedByLinkBandwidths(nc)) - && satisfiedBySpecifier(nc) - && (onlyImmutable || satisfiedBySignalStrength(nc)) - && (onlyImmutable || satisfiedByUids(nc)) - && (onlyImmutable || satisfiedBySSID(nc))) - && (onlyImmutable || satisfiedByRequestor(nc)); - } - - /** - * Check if our requirements are satisfied by the given {@code NetworkCapabilities}. - * - * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. - * - * @hide - */ - @SystemApi - public boolean satisfiedByNetworkCapabilities(@Nullable NetworkCapabilities nc) { - return satisfiedByNetworkCapabilities(nc, false); - } - - /** - * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}. - * - * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. - * - * @hide - */ - public boolean satisfiedByImmutableNetworkCapabilities(@Nullable NetworkCapabilities nc) { - return satisfiedByNetworkCapabilities(nc, true); - } - - /** - * Checks that our immutable capabilities are the same as those of the given - * {@code NetworkCapabilities} and return a String describing any difference. - * The returned String is empty if there is no difference. - * - * @hide - */ - public String describeImmutableDifferences(@Nullable NetworkCapabilities that) { - if (that == null) { - return "other NetworkCapabilities was null"; - } - - StringJoiner joiner = new StringJoiner(", "); - - // Ignore NOT_METERED being added or removed as it is effectively dynamic. http://b/63326103 - // TODO: properly support NOT_METERED as a mutable and requestable capability. - final long mask = ~MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_NOT_METERED); - long oldImmutableCapabilities = this.mNetworkCapabilities & mask; - long newImmutableCapabilities = that.mNetworkCapabilities & mask; - if (oldImmutableCapabilities != newImmutableCapabilities) { - String before = capabilityNamesOf(BitUtils.unpackBits(oldImmutableCapabilities)); - String after = capabilityNamesOf(BitUtils.unpackBits(newImmutableCapabilities)); - joiner.add(String.format("immutable capabilities changed: %s -> %s", before, after)); - } - - if (!equalsSpecifier(that)) { - NetworkSpecifier before = this.getNetworkSpecifier(); - NetworkSpecifier after = that.getNetworkSpecifier(); - joiner.add(String.format("specifier changed: %s -> %s", before, after)); - } - - if (!equalsTransportTypes(that)) { - String before = transportNamesOf(this.getTransportTypes()); - String after = transportNamesOf(that.getTransportTypes()); - joiner.add(String.format("transports changed: %s -> %s", before, after)); - } - - return joiner.toString(); - } - - /** - * Checks that our requestable capabilities are the same as those of the given - * {@code NetworkCapabilities}. - * - * @hide - */ - public boolean equalRequestableCapabilities(@Nullable NetworkCapabilities nc) { - if (nc == null) return false; - return (equalsNetCapabilitiesRequestable(nc) - && equalsTransportTypes(nc) - && equalsSpecifier(nc)); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj == null || (obj instanceof NetworkCapabilities == false)) return false; - NetworkCapabilities that = (NetworkCapabilities) obj; - return equalsNetCapabilities(that) - && equalsTransportTypes(that) - && equalsLinkBandwidths(that) - && equalsSignalStrength(that) - && equalsSpecifier(that) - && equalsTransportInfo(that) - && equalsUids(that) - && equalsSSID(that) - && equalsOwnerUid(that) - && equalsPrivateDnsBroken(that) - && equalsRequestor(that) - && equalsAdministratorUids(that); - } - - @Override - public int hashCode() { - return (int) (mNetworkCapabilities & 0xFFFFFFFF) - + ((int) (mNetworkCapabilities >> 32) * 3) - + ((int) (mUnwantedNetworkCapabilities & 0xFFFFFFFF) * 5) - + ((int) (mUnwantedNetworkCapabilities >> 32) * 7) - + ((int) (mTransportTypes & 0xFFFFFFFF) * 11) - + ((int) (mTransportTypes >> 32) * 13) - + mLinkUpBandwidthKbps * 17 - + mLinkDownBandwidthKbps * 19 - + Objects.hashCode(mNetworkSpecifier) * 23 - + mSignalStrength * 29 - + mOwnerUid * 31 - + Objects.hashCode(mUids) * 37 - + Objects.hashCode(mSSID) * 41 - + Objects.hashCode(mTransportInfo) * 43 - + Objects.hashCode(mPrivateDnsBroken) * 47 - + Objects.hashCode(mRequestorUid) * 53 - + Objects.hashCode(mRequestorPackageName) * 59 - + Arrays.hashCode(mAdministratorUids) * 61; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeLong(mNetworkCapabilities); - dest.writeLong(mUnwantedNetworkCapabilities); - dest.writeLong(mTransportTypes); - dest.writeInt(mLinkUpBandwidthKbps); - dest.writeInt(mLinkDownBandwidthKbps); - dest.writeParcelable((Parcelable) mNetworkSpecifier, flags); - dest.writeParcelable((Parcelable) mTransportInfo, flags); - dest.writeInt(mSignalStrength); - dest.writeArraySet(mUids); - dest.writeString(mSSID); - dest.writeBoolean(mPrivateDnsBroken); - dest.writeIntArray(getAdministratorUids()); - dest.writeInt(mOwnerUid); - dest.writeInt(mRequestorUid); - dest.writeString(mRequestorPackageName); - } - - public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR = - new Creator<NetworkCapabilities>() { - @Override - public NetworkCapabilities createFromParcel(Parcel in) { - NetworkCapabilities netCap = new NetworkCapabilities(); - - netCap.mNetworkCapabilities = in.readLong(); - netCap.mUnwantedNetworkCapabilities = in.readLong(); - netCap.mTransportTypes = in.readLong(); - netCap.mLinkUpBandwidthKbps = in.readInt(); - netCap.mLinkDownBandwidthKbps = in.readInt(); - netCap.mNetworkSpecifier = in.readParcelable(null); - netCap.mTransportInfo = in.readParcelable(null); - netCap.mSignalStrength = in.readInt(); - netCap.mUids = (ArraySet<UidRange>) in.readArraySet( - null /* ClassLoader, null for default */); - netCap.mSSID = in.readString(); - netCap.mPrivateDnsBroken = in.readBoolean(); - netCap.setAdministratorUids(in.createIntArray()); - netCap.mOwnerUid = in.readInt(); - netCap.mRequestorUid = in.readInt(); - netCap.mRequestorPackageName = in.readString(); - return netCap; - } - @Override - public NetworkCapabilities[] newArray(int size) { - return new NetworkCapabilities[size]; - } - }; - - @Override - public @NonNull String toString() { - final StringBuilder sb = new StringBuilder("["); - if (0 != mTransportTypes) { - sb.append(" Transports: "); - appendStringRepresentationOfBitMaskToStringBuilder(sb, mTransportTypes, - NetworkCapabilities::transportNameOf, "|"); - } - if (0 != mNetworkCapabilities) { - sb.append(" Capabilities: "); - appendStringRepresentationOfBitMaskToStringBuilder(sb, mNetworkCapabilities, - NetworkCapabilities::capabilityNameOf, "&"); - } - if (0 != mUnwantedNetworkCapabilities) { - sb.append(" Unwanted: "); - appendStringRepresentationOfBitMaskToStringBuilder(sb, mUnwantedNetworkCapabilities, - NetworkCapabilities::capabilityNameOf, "&"); - } - if (mLinkUpBandwidthKbps > 0) { - sb.append(" LinkUpBandwidth>=").append(mLinkUpBandwidthKbps).append("Kbps"); - } - if (mLinkDownBandwidthKbps > 0) { - sb.append(" LinkDnBandwidth>=").append(mLinkDownBandwidthKbps).append("Kbps"); - } - if (mNetworkSpecifier != null) { - sb.append(" Specifier: <").append(mNetworkSpecifier).append(">"); - } - if (mTransportInfo != null) { - sb.append(" TransportInfo: <").append(mTransportInfo).append(">"); - } - if (hasSignalStrength()) { - sb.append(" SignalStrength: ").append(mSignalStrength); - } - - if (null != mUids) { - if ((1 == mUids.size()) && (mUids.valueAt(0).count() == 1)) { - sb.append(" Uid: ").append(mUids.valueAt(0).start); - } else { - sb.append(" Uids: <").append(mUids).append(">"); - } - } - if (mOwnerUid != Process.INVALID_UID) { - sb.append(" OwnerUid: ").append(mOwnerUid); - } - - if (!ArrayUtils.isEmpty(mAdministratorUids)) { - sb.append(" AdminUids: ").append(Arrays.toString(mAdministratorUids)); - } - - if (mRequestorUid != Process.INVALID_UID) { - sb.append(" RequestorUid: ").append(mRequestorUid); - } - - if (mRequestorPackageName != null) { - sb.append(" RequestorPkg: ").append(mRequestorPackageName); - } - - if (null != mSSID) { - sb.append(" SSID: ").append(mSSID); - } - - - if (mPrivateDnsBroken) { - sb.append(" PrivateDnsBroken"); - } - - sb.append("]"); - return sb.toString(); - } - - - private interface NameOf { - String nameOf(int value); - } - - /** - * @hide - */ - public static void appendStringRepresentationOfBitMaskToStringBuilder(@NonNull StringBuilder sb, - long bitMask, @NonNull NameOf nameFetcher, @NonNull String separator) { - int bitPos = 0; - boolean firstElementAdded = false; - while (bitMask != 0) { - if ((bitMask & 1) != 0) { - if (firstElementAdded) { - sb.append(separator); - } else { - firstElementAdded = true; - } - sb.append(nameFetcher.nameOf(bitPos)); - } - bitMask >>= 1; - ++bitPos; - } - } - - /** @hide */ - public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) { - final long token = proto.start(fieldId); - - for (int transport : getTransportTypes()) { - proto.write(NetworkCapabilitiesProto.TRANSPORTS, transport); - } - - for (int capability : getCapabilities()) { - proto.write(NetworkCapabilitiesProto.CAPABILITIES, capability); - } - - proto.write(NetworkCapabilitiesProto.LINK_UP_BANDWIDTH_KBPS, mLinkUpBandwidthKbps); - proto.write(NetworkCapabilitiesProto.LINK_DOWN_BANDWIDTH_KBPS, mLinkDownBandwidthKbps); - - if (mNetworkSpecifier != null) { - proto.write(NetworkCapabilitiesProto.NETWORK_SPECIFIER, mNetworkSpecifier.toString()); - } - if (mTransportInfo != null) { - // TODO b/120653863: write transport-specific info to proto? - } - - proto.write(NetworkCapabilitiesProto.CAN_REPORT_SIGNAL_STRENGTH, hasSignalStrength()); - proto.write(NetworkCapabilitiesProto.SIGNAL_STRENGTH, mSignalStrength); - - proto.end(token); - } - - /** - * @hide - */ - public static @NonNull String capabilityNamesOf(@Nullable @NetCapability int[] capabilities) { - StringJoiner joiner = new StringJoiner("|"); - if (capabilities != null) { - for (int c : capabilities) { - joiner.add(capabilityNameOf(c)); - } - } - return joiner.toString(); - } - - /** - * @hide - */ - public static @NonNull String capabilityNameOf(@NetCapability int capability) { - switch (capability) { - case NET_CAPABILITY_MMS: return "MMS"; - case NET_CAPABILITY_SUPL: return "SUPL"; - case NET_CAPABILITY_DUN: return "DUN"; - case NET_CAPABILITY_FOTA: return "FOTA"; - case NET_CAPABILITY_IMS: return "IMS"; - case NET_CAPABILITY_CBS: return "CBS"; - case NET_CAPABILITY_WIFI_P2P: return "WIFI_P2P"; - case NET_CAPABILITY_IA: return "IA"; - case NET_CAPABILITY_RCS: return "RCS"; - case NET_CAPABILITY_XCAP: return "XCAP"; - case NET_CAPABILITY_EIMS: return "EIMS"; - case NET_CAPABILITY_NOT_METERED: return "NOT_METERED"; - case NET_CAPABILITY_INTERNET: return "INTERNET"; - case NET_CAPABILITY_NOT_RESTRICTED: return "NOT_RESTRICTED"; - case NET_CAPABILITY_TRUSTED: return "TRUSTED"; - case NET_CAPABILITY_NOT_VPN: return "NOT_VPN"; - case NET_CAPABILITY_VALIDATED: return "VALIDATED"; - case NET_CAPABILITY_CAPTIVE_PORTAL: return "CAPTIVE_PORTAL"; - case NET_CAPABILITY_NOT_ROAMING: return "NOT_ROAMING"; - case NET_CAPABILITY_FOREGROUND: return "FOREGROUND"; - case NET_CAPABILITY_NOT_CONGESTED: return "NOT_CONGESTED"; - case NET_CAPABILITY_NOT_SUSPENDED: return "NOT_SUSPENDED"; - case NET_CAPABILITY_OEM_PAID: return "OEM_PAID"; - case NET_CAPABILITY_MCX: return "MCX"; - case NET_CAPABILITY_PARTIAL_CONNECTIVITY: return "PARTIAL_CONNECTIVITY"; - case NET_CAPABILITY_TEMPORARILY_NOT_METERED: return "TEMPORARILY_NOT_METERED"; - case NET_CAPABILITY_OEM_PRIVATE: return "OEM_PRIVATE"; - case NET_CAPABILITY_VEHICLE_INTERNAL: return "NET_CAPABILITY_VEHICLE_INTERNAL"; - case NET_CAPABILITY_NOT_VCN_MANAGED: return "NOT_VCN_MANAGED"; - default: return Integer.toString(capability); - } - } - - /** - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static @NonNull String transportNamesOf(@Nullable @Transport int[] types) { - StringJoiner joiner = new StringJoiner("|"); - if (types != null) { - for (int t : types) { - joiner.add(transportNameOf(t)); - } - } - return joiner.toString(); - } - - /** - * @hide - */ - public static @NonNull String transportNameOf(@Transport int transport) { - if (!isValidTransport(transport)) { - return "UNKNOWN"; - } - return TRANSPORT_NAMES[transport]; - } - - private static void checkValidTransportType(@Transport int transport) { - Preconditions.checkArgument( - isValidTransport(transport), "Invalid TransportType " + transport); - } - - private static boolean isValidCapability(@NetworkCapabilities.NetCapability int capability) { - return capability >= MIN_NET_CAPABILITY && capability <= MAX_NET_CAPABILITY; - } - - private static void checkValidCapability(@NetworkCapabilities.NetCapability int capability) { - Preconditions.checkArgument(isValidCapability(capability), - "NetworkCapability " + capability + "out of range"); - } - - /** - * Check if this {@code NetworkCapability} instance is metered. - * - * @return {@code true} if {@code NET_CAPABILITY_NOT_METERED} is not set on this instance. - * @hide - */ - public boolean isMetered() { - return !hasCapability(NET_CAPABILITY_NOT_METERED); - } - - /** - * Check if private dns is broken. - * - * @return {@code true} if {@code mPrivateDnsBroken} is set when private DNS is broken. - * @hide - */ - public boolean isPrivateDnsBroken() { - return mPrivateDnsBroken; - } - - /** - * Set mPrivateDnsBroken to true when private dns is broken. - * - * @param broken the status of private DNS to be set. - * @hide - */ - public void setPrivateDnsBroken(boolean broken) { - mPrivateDnsBroken = broken; - } - - private boolean equalsPrivateDnsBroken(NetworkCapabilities nc) { - return mPrivateDnsBroken == nc.mPrivateDnsBroken; - } - - /** - * Set the UID of the app making the request. - * - * For instances of NetworkCapabilities representing a request, sets the - * UID of the app making the request. For a network created by the system, - * sets the UID of the only app whose requests can match this network. - * This can be set to {@link Process#INVALID_UID} if there is no such app, - * or if this instance of NetworkCapabilities is about to be sent to a - * party that should not learn about this. - * - * @param uid UID of the app. - * @hide - */ - public @NonNull NetworkCapabilities setRequestorUid(int uid) { - mRequestorUid = uid; - return this; - } - - /** - * Returns the UID of the app making the request. - * - * For a NetworkRequest being made by an app, contains the app's UID. For a network - * created by the system, contains the UID of the only app whose requests can match - * this network, or {@link Process#INVALID_UID} if none or if the - * caller does not have permission to learn about this. - * - * @return the uid of the app making the request. - * @hide - */ - public int getRequestorUid() { - return mRequestorUid; - } - - /** - * Set the package name of the app making the request. - * - * For instances of NetworkCapabilities representing a request, sets the - * package name of the app making the request. For a network created by the system, - * sets the package name of the only app whose requests can match this network. - * This can be set to null if there is no such app, or if this instance of - * NetworkCapabilities is about to be sent to a party that should not learn about this. - * - * @param packageName package name of the app. - * @hide - */ - public @NonNull NetworkCapabilities setRequestorPackageName(@NonNull String packageName) { - mRequestorPackageName = packageName; - return this; - } - - /** - * Returns the package name of the app making the request. - * - * For a NetworkRequest being made by an app, contains the app's package name. For a - * network created by the system, contains the package name of the only app whose - * requests can match this network, or null if none or if the caller does not have - * permission to learn about this. - * - * @return the package name of the app making the request. - * @hide - */ - @Nullable - public String getRequestorPackageName() { - return mRequestorPackageName; - } - - /** - * Set the uid and package name of the app causing this network to exist. - * - * {@see #setRequestorUid} and {@link #setRequestorPackageName} - * - * @param uid UID of the app. - * @param packageName package name of the app. - * @hide - */ - public @NonNull NetworkCapabilities setRequestorUidAndPackageName( - int uid, @NonNull String packageName) { - return setRequestorUid(uid).setRequestorPackageName(packageName); - } - - /** - * Test whether the passed NetworkCapabilities satisfies the requestor restrictions of this - * capabilities. - * - * This method is called on the NetworkCapabilities embedded in a request with the - * capabilities of an available network. If the available network, sets a specific - * requestor (by uid and optionally package name), then this will only match a request from the - * same app. If either of the capabilities have an unset uid or package name, then it matches - * everything. - * <p> - * nc is assumed nonnull. Else, NPE. - */ - private boolean satisfiedByRequestor(NetworkCapabilities nc) { - // No uid set, matches everything. - if (mRequestorUid == Process.INVALID_UID || nc.mRequestorUid == Process.INVALID_UID) { - return true; - } - // uids don't match. - if (mRequestorUid != nc.mRequestorUid) return false; - // No package names set, matches everything - if (null == nc.mRequestorPackageName || null == mRequestorPackageName) return true; - // check for package name match. - return TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName); - } - - /** - * Combine requestor info of the capabilities. - * <p> - * This is only legal if either the requestor info of this object is reset, or both info are - * equal. - * nc is assumed nonnull. - */ - private void combineRequestor(@NonNull NetworkCapabilities nc) { - if (mRequestorUid != Process.INVALID_UID && mRequestorUid != nc.mOwnerUid) { - throw new IllegalStateException("Can't combine two uids"); - } - if (mRequestorPackageName != null - && !mRequestorPackageName.equals(nc.mRequestorPackageName)) { - throw new IllegalStateException("Can't combine two package names"); - } - setRequestorUid(nc.mRequestorUid); - setRequestorPackageName(nc.mRequestorPackageName); - } - - private boolean equalsRequestor(NetworkCapabilities nc) { - return mRequestorUid == nc.mRequestorUid - && TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName); - } - - /** - * Builder class for NetworkCapabilities. - * - * This class is mainly for for {@link NetworkAgent} instances to use. Many fields in - * the built class require holding a signature permission to use - mostly - * {@link android.Manifest.permission.NETWORK_FACTORY}, but refer to the specific - * description of each setter. As this class lives entirely in app space it does not - * enforce these restrictions itself but the system server clears out the relevant - * fields when receiving a NetworkCapabilities object from a caller without the - * appropriate permission. - * - * Apps don't use this builder directly. Instead, they use {@link NetworkRequest} via - * its builder object. - * - * @hide - */ - @SystemApi - public static final class Builder { - private final NetworkCapabilities mCaps; - - /** - * Creates a new Builder to construct NetworkCapabilities objects. - */ - public Builder() { - mCaps = new NetworkCapabilities(); - } - - /** - * Creates a new Builder of NetworkCapabilities from an existing instance. - */ - public Builder(@NonNull final NetworkCapabilities nc) { - Objects.requireNonNull(nc); - mCaps = new NetworkCapabilities(nc); - } - - /** - * Adds the given transport type. - * - * Multiple transports may be added. Note that when searching for a network to satisfy a - * request, satisfying any of the transports listed in the request will satisfy the request. - * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a - * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network - * to be selected. This is logically different than - * {@code NetworkCapabilities.NET_CAPABILITY_*}. - * - * @param transportType the transport type to be added or removed. - * @return this builder - */ - @NonNull - public Builder addTransportType(@Transport int transportType) { - checkValidTransportType(transportType); - mCaps.addTransportType(transportType); - return this; - } - - /** - * Removes the given transport type. - * - * {@see #addTransportType}. - * - * @param transportType the transport type to be added or removed. - * @return this builder - */ - @NonNull - public Builder removeTransportType(@Transport int transportType) { - checkValidTransportType(transportType); - mCaps.removeTransportType(transportType); - return this; - } - - /** - * Adds the given capability. - * - * @param capability the capability - * @return this builder - */ - @NonNull - public Builder addCapability(@NetCapability final int capability) { - mCaps.setCapability(capability, true); - return this; - } - - /** - * Removes the given capability. - * - * @param capability the capability - * @return this builder - */ - @NonNull - public Builder removeCapability(@NetCapability final int capability) { - mCaps.setCapability(capability, false); - return this; - } - - /** - * Sets the owner UID. - * - * The default value is {@link Process#INVALID_UID}. Pass this value to reset. - * - * Note: for security the system will clear out this field when received from a - * non-privileged source. - * - * @param ownerUid the owner UID - * @return this builder - */ - @NonNull - @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) - public Builder setOwnerUid(final int ownerUid) { - mCaps.setOwnerUid(ownerUid); - return this; - } - - /** - * Sets the list of UIDs that are administrators of this network. - * - * <p>UIDs included in administratorUids gain administrator privileges over this - * Network. Examples of UIDs that should be included in administratorUids are: - * <ul> - * <li>Carrier apps with privileges for the relevant subscription - * <li>Active VPN apps - * <li>Other application groups with a particular Network-related role - * </ul> - * - * <p>In general, user-supplied networks (such as WiFi networks) do not have - * administrators. - * - * <p>An app is granted owner privileges over Networks that it supplies. The owner - * UID MUST always be included in administratorUids. - * - * The default value is the empty array. Pass an empty array to reset. - * - * Note: for security the system will clear out this field when received from a - * non-privileged source, such as an app using reflection to call this or - * mutate the member in the built object. - * - * @param administratorUids the UIDs to be set as administrators of this Network. - * @return this builder - */ - @NonNull - @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) - public Builder setAdministratorUids(@NonNull final int[] administratorUids) { - Objects.requireNonNull(administratorUids); - mCaps.setAdministratorUids(administratorUids); - return this; - } - - /** - * Sets the upstream bandwidth of the link. - * - * Sets the upstream bandwidth for this network in Kbps. This always only refers to - * the estimated first hop transport bandwidth. - * <p> - * Note that when used to request a network, this specifies the minimum acceptable. - * When received as the state of an existing network this specifies the typical - * first hop bandwidth expected. This is never measured, but rather is inferred - * from technology type and other link parameters. It could be used to differentiate - * between very slow 1xRTT cellular links and other faster networks or even between - * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between - * fast backhauls and slow backhauls. - * - * @param upKbps the estimated first hop upstream (device to network) bandwidth. - * @return this builder - */ - @NonNull - public Builder setLinkUpstreamBandwidthKbps(final int upKbps) { - mCaps.setLinkUpstreamBandwidthKbps(upKbps); - return this; - } - - /** - * Sets the downstream bandwidth for this network in Kbps. This always only refers to - * the estimated first hop transport bandwidth. - * <p> - * Note that when used to request a network, this specifies the minimum acceptable. - * When received as the state of an existing network this specifies the typical - * first hop bandwidth expected. This is never measured, but rather is inferred - * from technology type and other link parameters. It could be used to differentiate - * between very slow 1xRTT cellular links and other faster networks or even between - * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between - * fast backhauls and slow backhauls. - * - * @param downKbps the estimated first hop downstream (network to device) bandwidth. - * @return this builder - */ - @NonNull - public Builder setLinkDownstreamBandwidthKbps(final int downKbps) { - mCaps.setLinkDownstreamBandwidthKbps(downKbps); - return this; - } - - /** - * Sets the optional bearer specific network specifier. - * This has no meaning if a single transport is also not specified, so calling - * this without a single transport set will generate an exception, as will - * subsequently adding or removing transports after this is set. - * </p> - * - * @param specifier a concrete, parcelable framework class that extends NetworkSpecifier, - * or null to clear it. - * @return this builder - */ - @NonNull - public Builder setNetworkSpecifier(@Nullable final NetworkSpecifier specifier) { - mCaps.setNetworkSpecifier(specifier); - return this; - } - - /** - * Sets the optional transport specific information. - * - * @param info A concrete, parcelable framework class that extends {@link TransportInfo}, - * or null to clear it. - * @return this builder - */ - @NonNull - public Builder setTransportInfo(@Nullable final TransportInfo info) { - mCaps.setTransportInfo(info); - return this; - } - - /** - * Sets the signal strength. This is a signed integer, with higher values indicating a - * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the - * same RSSI units reported by wifi code. - * <p> - * Note that when used to register a network callback, this specifies the minimum - * acceptable signal strength. When received as the state of an existing network it - * specifies the current value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means - * no value when received and has no effect when requesting a callback. - * - * Note: for security the system will throw if it receives a NetworkRequest where - * the underlying NetworkCapabilities has this member set from a source that does - * not hold the {@link android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP} - * permission. Apps with this permission can use this indirectly through - * {@link android.net.NetworkRequest}. - * - * @param signalStrength the bearer-specific signal strength. - * @return this builder - */ - @NonNull - @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) - public Builder setSignalStrength(final int signalStrength) { - mCaps.setSignalStrength(signalStrength); - return this; - } - - /** - * Sets the SSID of this network. - * - * Note: for security the system will clear out this field when received from a - * non-privileged source, like an app using reflection to set this. - * - * @param ssid the SSID, or null to clear it. - * @return this builder - */ - @NonNull - @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) - public Builder setSsid(@Nullable final String ssid) { - mCaps.setSSID(ssid); - return this; - } - - /** - * Set the uid of the app causing this network to exist. - * - * Note: for security the system will clear out this field when received from a - * non-privileged source. - * - * @param uid UID of the app. - * @return this builder - */ - @NonNull - @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) - public Builder setRequestorUid(final int uid) { - mCaps.setRequestorUid(uid); - return this; - } - - /** - * Set the package name of the app causing this network to exist. - * - * Note: for security the system will clear out this field when received from a - * non-privileged source. - * - * @param packageName package name of the app, or null to clear it. - * @return this builder - */ - @NonNull - @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) - public Builder setRequestorPackageName(@Nullable final String packageName) { - mCaps.setRequestorPackageName(packageName); - return this; - } - - /** - * Builds the instance of the capabilities. - * - * @return the built instance of NetworkCapabilities. - */ - @NonNull - public NetworkCapabilities build() { - if (mCaps.getOwnerUid() != Process.INVALID_UID) { - if (!ArrayUtils.contains(mCaps.getAdministratorUids(), mCaps.getOwnerUid())) { - throw new IllegalStateException("The owner UID must be included in " - + " administrator UIDs."); - } - } - return new NetworkCapabilities(mCaps); - } - } -} diff --git a/core/java/android/net/NetworkConfig.java b/core/java/android/net/NetworkConfig.java deleted file mode 100644 index 32a2cda00370..000000000000 --- a/core/java/android/net/NetworkConfig.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import java.util.Locale; - -/** - * Describes the buildtime configuration of a network. - * Holds settings read from resources. - * @hide - */ -public class NetworkConfig { - /** - * Human readable string - */ - public String name; - - /** - * Type from ConnectivityManager - */ - public int type; - - /** - * the radio number from radio attributes config - */ - public int radio; - - /** - * higher number == higher priority when turning off connections - */ - public int priority; - - /** - * indicates the boot time dependencyMet setting - */ - public boolean dependencyMet; - - /** - * indicates the default restoral timer in seconds - * if the network is used as a special network feature - * -1 indicates no restoration of default - */ - public int restoreTime; - - /** - * input string from config.xml resource. Uses the form: - * [Connection name],[ConnectivityManager connection type], - * [associated radio-type],[priority],[dependencyMet] - */ - public NetworkConfig(String init) { - String fragments[] = init.split(","); - name = fragments[0].trim().toLowerCase(Locale.ROOT); - type = Integer.parseInt(fragments[1]); - radio = Integer.parseInt(fragments[2]); - priority = Integer.parseInt(fragments[3]); - restoreTime = Integer.parseInt(fragments[4]); - dependencyMet = Boolean.parseBoolean(fragments[5]); - } - - /** - * Indicates if this network is supposed to be default-routable - */ - public boolean isDefault() { - return (type == radio); - } -} diff --git a/core/java/android/net/NetworkInfo.aidl b/core/java/android/net/NetworkInfo.aidl deleted file mode 100644 index f50187302966..000000000000 --- a/core/java/android/net/NetworkInfo.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2007, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -parcelable NetworkInfo; diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java deleted file mode 100644 index d752901e2eb0..000000000000 --- a/core/java/android/net/NetworkInfo.java +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.compat.annotation.UnsupportedAppUsage; -import android.os.Parcel; -import android.os.Parcelable; -import android.telephony.Annotation.NetworkType; -import android.text.TextUtils; - -import com.android.internal.annotations.VisibleForTesting; - -import java.util.EnumMap; - -/** - * Describes the status of a network interface. - * <p>Use {@link ConnectivityManager#getActiveNetworkInfo()} to get an instance that represents - * the current network connection. - * - * @deprecated Callers should instead use the {@link ConnectivityManager.NetworkCallback} API to - * learn about connectivity changes, or switch to use - * {@link ConnectivityManager#getNetworkCapabilities} or - * {@link ConnectivityManager#getLinkProperties} to get information synchronously. Keep - * in mind that while callbacks are guaranteed to be called for every event in order, - * synchronous calls have no such constraints, and as such it is unadvisable to use the - * synchronous methods inside the callbacks as they will often not offer a view of - * networking that is consistent (that is: they may return a past or a future state with - * respect to the event being processed by the callback). Instead, callers are advised - * to only use the arguments of the callbacks, possibly memorizing the specific bits of - * information they need to keep from one callback to another. - */ -@Deprecated -public class NetworkInfo implements Parcelable { - - /** - * Coarse-grained network state. This is probably what most applications should - * use, rather than {@link android.net.NetworkInfo.DetailedState DetailedState}. - * The mapping between the two is as follows: - * <br/><br/> - * <table> - * <tr><td><b>Detailed state</b></td><td><b>Coarse-grained state</b></td></tr> - * <tr><td><code>IDLE</code></td><td><code>DISCONNECTED</code></td></tr> - * <tr><td><code>SCANNING</code></td><td><code>DISCONNECTED</code></td></tr> - * <tr><td><code>CONNECTING</code></td><td><code>CONNECTING</code></td></tr> - * <tr><td><code>AUTHENTICATING</code></td><td><code>CONNECTING</code></td></tr> - * <tr><td><code>OBTAINING_IPADDR</code></td><td><code>CONNECTING</code></td></tr> - * <tr><td><code>VERIFYING_POOR_LINK</code></td><td><code>CONNECTING</code></td></tr> - * <tr><td><code>CAPTIVE_PORTAL_CHECK</code></td><td><code>CONNECTING</code></td></tr> - * <tr><td><code>CONNECTED</code></td><td><code>CONNECTED</code></td></tr> - * <tr><td><code>SUSPENDED</code></td><td><code>SUSPENDED</code></td></tr> - * <tr><td><code>DISCONNECTING</code></td><td><code>DISCONNECTING</code></td></tr> - * <tr><td><code>DISCONNECTED</code></td><td><code>DISCONNECTED</code></td></tr> - * <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr> - * <tr><td><code>BLOCKED</code></td><td><code>DISCONNECTED</code></td></tr> - * </table> - * - * @deprecated See {@link NetworkInfo}. - */ - @Deprecated - public enum State { - CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN - } - - /** - * The fine-grained state of a network connection. This level of detail - * is probably of interest to few applications. Most should use - * {@link android.net.NetworkInfo.State State} instead. - * - * @deprecated See {@link NetworkInfo}. - */ - @Deprecated - public enum DetailedState { - /** Ready to start data connection setup. */ - IDLE, - /** Searching for an available access point. */ - SCANNING, - /** Currently setting up data connection. */ - CONNECTING, - /** Network link established, performing authentication. */ - AUTHENTICATING, - /** Awaiting response from DHCP server in order to assign IP address information. */ - OBTAINING_IPADDR, - /** IP traffic should be available. */ - CONNECTED, - /** IP traffic is suspended */ - SUSPENDED, - /** Currently tearing down data connection. */ - DISCONNECTING, - /** IP traffic not available. */ - DISCONNECTED, - /** Attempt to connect failed. */ - FAILED, - /** Access to this network is blocked. */ - BLOCKED, - /** Link has poor connectivity. */ - VERIFYING_POOR_LINK, - /** Checking if network is a captive portal */ - CAPTIVE_PORTAL_CHECK - } - - /** - * This is the map described in the Javadoc comment above. The positions - * of the elements of the array must correspond to the ordinal values - * of <code>DetailedState</code>. - */ - private static final EnumMap<DetailedState, State> stateMap = - new EnumMap<DetailedState, State>(DetailedState.class); - - static { - stateMap.put(DetailedState.IDLE, State.DISCONNECTED); - stateMap.put(DetailedState.SCANNING, State.DISCONNECTED); - stateMap.put(DetailedState.CONNECTING, State.CONNECTING); - stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING); - stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING); - stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING); - stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING); - stateMap.put(DetailedState.CONNECTED, State.CONNECTED); - stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED); - stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING); - stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED); - stateMap.put(DetailedState.FAILED, State.DISCONNECTED); - stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED); - } - - private int mNetworkType; - private int mSubtype; - private String mTypeName; - private String mSubtypeName; - @NonNull - private State mState; - @NonNull - private DetailedState mDetailedState; - private String mReason; - private String mExtraInfo; - private boolean mIsFailover; - private boolean mIsAvailable; - private boolean mIsRoaming; - - /** - * Create a new instance of NetworkInfo. - * - * This may be useful for apps to write unit tests. - * - * @param type the legacy type of the network, as one of the ConnectivityManager.TYPE_* - * constants. - * @param subtype the subtype if applicable, as one of the TelephonyManager.NETWORK_TYPE_* - * constants. - * @param typeName a human-readable string for the network type, or an empty string or null. - * @param subtypeName a human-readable string for the subtype, or an empty string or null. - */ - public NetworkInfo(int type, @NetworkType int subtype, - @Nullable String typeName, @Nullable String subtypeName) { - if (!ConnectivityManager.isNetworkTypeValid(type) - && type != ConnectivityManager.TYPE_NONE) { - throw new IllegalArgumentException("Invalid network type: " + type); - } - mNetworkType = type; - mSubtype = subtype; - mTypeName = typeName; - mSubtypeName = subtypeName; - setDetailedState(DetailedState.IDLE, null, null); - mState = State.UNKNOWN; - } - - /** {@hide} */ - @UnsupportedAppUsage - public NetworkInfo(NetworkInfo source) { - if (source != null) { - synchronized (source) { - mNetworkType = source.mNetworkType; - mSubtype = source.mSubtype; - mTypeName = source.mTypeName; - mSubtypeName = source.mSubtypeName; - mState = source.mState; - mDetailedState = source.mDetailedState; - mReason = source.mReason; - mExtraInfo = source.mExtraInfo; - mIsFailover = source.mIsFailover; - mIsAvailable = source.mIsAvailable; - mIsRoaming = source.mIsRoaming; - } - } - } - - /** - * Reports the type of network to which the - * info in this {@code NetworkInfo} pertains. - * @return one of {@link ConnectivityManager#TYPE_MOBILE}, {@link - * ConnectivityManager#TYPE_WIFI}, {@link ConnectivityManager#TYPE_WIMAX}, {@link - * ConnectivityManager#TYPE_ETHERNET}, {@link ConnectivityManager#TYPE_BLUETOOTH}, or other - * types defined by {@link ConnectivityManager}. - * @deprecated Callers should switch to checking {@link NetworkCapabilities#hasTransport} - * instead with one of the NetworkCapabilities#TRANSPORT_* constants : - * {@link #getType} and {@link #getTypeName} cannot account for networks using - * multiple transports. Note that generally apps should not care about transport; - * {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED} and - * {@link NetworkCapabilities#getLinkDownstreamBandwidthKbps} are calls that - * apps concerned with meteredness or bandwidth should be looking at, as they - * offer this information with much better accuracy. - */ - @Deprecated - public int getType() { - synchronized (this) { - return mNetworkType; - } - } - - /** - * @deprecated Use {@link NetworkCapabilities} instead - * @hide - */ - @Deprecated - public void setType(int type) { - synchronized (this) { - mNetworkType = type; - } - } - - /** - * Return a network-type-specific integer describing the subtype - * of the network. - * @return the network subtype - * @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead. - */ - @Deprecated - public int getSubtype() { - synchronized (this) { - return mSubtype; - } - } - - /** - * @hide - */ - @UnsupportedAppUsage - public void setSubtype(int subtype, String subtypeName) { - synchronized (this) { - mSubtype = subtype; - mSubtypeName = subtypeName; - } - } - - /** - * Return a human-readable name describe the type of the network, - * for example "WIFI" or "MOBILE". - * @return the name of the network type - * @deprecated Callers should switch to checking {@link NetworkCapabilities#hasTransport} - * instead with one of the NetworkCapabilities#TRANSPORT_* constants : - * {@link #getType} and {@link #getTypeName} cannot account for networks using - * multiple transports. Note that generally apps should not care about transport; - * {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED} and - * {@link NetworkCapabilities#getLinkDownstreamBandwidthKbps} are calls that - * apps concerned with meteredness or bandwidth should be looking at, as they - * offer this information with much better accuracy. - */ - @Deprecated - public String getTypeName() { - synchronized (this) { - return mTypeName; - } - } - - /** - * Return a human-readable name describing the subtype of the network. - * @return the name of the network subtype - * @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead. - */ - @Deprecated - public String getSubtypeName() { - synchronized (this) { - return mSubtypeName; - } - } - - /** - * Indicates whether network connectivity exists or is in the process - * of being established. This is good for applications that need to - * do anything related to the network other than read or write data. - * For the latter, call {@link #isConnected()} instead, which guarantees - * that the network is fully usable. - * @return {@code true} if network connectivity exists or is in the process - * of being established, {@code false} otherwise. - * @deprecated Apps should instead use the - * {@link android.net.ConnectivityManager.NetworkCallback} API to - * learn about connectivity changes. - * {@link ConnectivityManager#registerDefaultNetworkCallback} and - * {@link ConnectivityManager#registerNetworkCallback}. These will - * give a more accurate picture of the connectivity state of - * the device and let apps react more easily and quickly to changes. - */ - @Deprecated - public boolean isConnectedOrConnecting() { - synchronized (this) { - return mState == State.CONNECTED || mState == State.CONNECTING; - } - } - - /** - * Indicates whether network connectivity exists and it is possible to establish - * connections and pass data. - * <p>Always call this before attempting to perform data transactions. - * @return {@code true} if network connectivity exists, {@code false} otherwise. - * @deprecated Apps should instead use the - * {@link android.net.ConnectivityManager.NetworkCallback} API to - * learn about connectivity changes. See - * {@link ConnectivityManager#registerDefaultNetworkCallback} and - * {@link ConnectivityManager#registerNetworkCallback}. These will - * give a more accurate picture of the connectivity state of - * the device and let apps react more easily and quickly to changes. - */ - @Deprecated - public boolean isConnected() { - synchronized (this) { - return mState == State.CONNECTED; - } - } - - /** - * Indicates whether network connectivity is possible. A network is unavailable - * when a persistent or semi-persistent condition prevents the possibility - * of connecting to that network. Examples include - * <ul> - * <li>The device is out of the coverage area for any network of this type.</li> - * <li>The device is on a network other than the home network (i.e., roaming), and - * data roaming has been disabled.</li> - * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li> - * </ul> - * Since Android L, this always returns {@code true}, because the system only - * returns info for available networks. - * @return {@code true} if the network is available, {@code false} otherwise - * @deprecated Apps should instead use the - * {@link android.net.ConnectivityManager.NetworkCallback} API to - * learn about connectivity changes. - * {@link ConnectivityManager#registerDefaultNetworkCallback} and - * {@link ConnectivityManager#registerNetworkCallback}. These will - * give a more accurate picture of the connectivity state of - * the device and let apps react more easily and quickly to changes. - */ - @Deprecated - public boolean isAvailable() { - synchronized (this) { - return mIsAvailable; - } - } - - /** - * Sets if the network is available, ie, if the connectivity is possible. - * @param isAvailable the new availability value. - * @deprecated Use {@link NetworkCapabilities} instead - * - * @hide - */ - @Deprecated - @UnsupportedAppUsage - public void setIsAvailable(boolean isAvailable) { - synchronized (this) { - mIsAvailable = isAvailable; - } - } - - /** - * Indicates whether the current attempt to connect to the network - * resulted from the ConnectivityManager trying to fail over to this - * network following a disconnect from another network. - * @return {@code true} if this is a failover attempt, {@code false} - * otherwise. - * @deprecated This field is not populated in recent Android releases, - * and does not make a lot of sense in a multi-network world. - */ - @Deprecated - public boolean isFailover() { - synchronized (this) { - return mIsFailover; - } - } - - /** - * Set the failover boolean. - * @param isFailover {@code true} to mark the current connection attempt - * as a failover. - * @deprecated This hasn't been set in any recent Android release. - * @hide - */ - @Deprecated - @UnsupportedAppUsage - public void setFailover(boolean isFailover) { - synchronized (this) { - mIsFailover = isFailover; - } - } - - /** - * Indicates whether the device is currently roaming on this network. When - * {@code true}, it suggests that use of data on this network may incur - * extra costs. - * - * @return {@code true} if roaming is in effect, {@code false} otherwise. - * @deprecated Callers should switch to checking - * {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING} - * instead, since that handles more complex situations, such as - * VPNs. - */ - @Deprecated - public boolean isRoaming() { - synchronized (this) { - return mIsRoaming; - } - } - - /** - * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING} instead. - * {@hide} - */ - @VisibleForTesting - @Deprecated - @UnsupportedAppUsage - public void setRoaming(boolean isRoaming) { - synchronized (this) { - mIsRoaming = isRoaming; - } - } - - /** - * Reports the current coarse-grained state of the network. - * @return the coarse-grained state - * @deprecated Apps should instead use the - * {@link android.net.ConnectivityManager.NetworkCallback} API to - * learn about connectivity changes. - * {@link ConnectivityManager#registerDefaultNetworkCallback} and - * {@link ConnectivityManager#registerNetworkCallback}. These will - * give a more accurate picture of the connectivity state of - * the device and let apps react more easily and quickly to changes. - */ - @Deprecated - public State getState() { - synchronized (this) { - return mState; - } - } - - /** - * Reports the current fine-grained state of the network. - * @return the fine-grained state - * @deprecated Apps should instead use the - * {@link android.net.ConnectivityManager.NetworkCallback} API to - * learn about connectivity changes. See - * {@link ConnectivityManager#registerDefaultNetworkCallback} and - * {@link ConnectivityManager#registerNetworkCallback}. These will - * give a more accurate picture of the connectivity state of - * the device and let apps react more easily and quickly to changes. - */ - @Deprecated - public @NonNull DetailedState getDetailedState() { - synchronized (this) { - return mDetailedState; - } - } - - /** - * Sets the fine-grained state of the network. - * - * This is only useful for testing. - * - * @param detailedState the {@link DetailedState}. - * @param reason a {@code String} indicating the reason for the state change, - * if one was supplied. May be {@code null}. - * @param extraInfo an optional {@code String} providing addditional network state - * information passed up from the lower networking layers. - * @deprecated Use {@link NetworkCapabilities} instead. - */ - @Deprecated - public void setDetailedState(@NonNull DetailedState detailedState, @Nullable String reason, - @Nullable String extraInfo) { - synchronized (this) { - this.mDetailedState = detailedState; - this.mState = stateMap.get(detailedState); - this.mReason = reason; - this.mExtraInfo = extraInfo; - } - } - - /** - * Set the extraInfo field. - * @param extraInfo an optional {@code String} providing addditional network state - * information passed up from the lower networking layers. - * @deprecated See {@link NetworkInfo#getExtraInfo}. - * @hide - */ - @Deprecated - public void setExtraInfo(String extraInfo) { - synchronized (this) { - this.mExtraInfo = extraInfo; - } - } - - /** - * Report the reason an attempt to establish connectivity failed, - * if one is available. - * @return the reason for failure, or null if not available - * @deprecated This method does not have a consistent contract that could make it useful - * to callers. - */ - public String getReason() { - synchronized (this) { - return mReason; - } - } - - /** - * Report the extra information about the network state, if any was - * provided by the lower networking layers. - * @return the extra information, or null if not available - * @deprecated Use other services e.g. WifiManager to get additional information passed up from - * the lower networking layers. - */ - @Deprecated - public String getExtraInfo() { - synchronized (this) { - return mExtraInfo; - } - } - - @Override - public String toString() { - synchronized (this) { - final StringBuilder builder = new StringBuilder("["); - builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()). - append("], state: ").append(mState).append("/").append(mDetailedState). - append(", reason: ").append(mReason == null ? "(unspecified)" : mReason). - append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo). - append(", failover: ").append(mIsFailover). - append(", available: ").append(mIsAvailable). - append(", roaming: ").append(mIsRoaming). - append("]"); - return builder.toString(); - } - } - - /** - * Returns a brief summary string suitable for debugging. - * @hide - */ - public String toShortString() { - synchronized (this) { - final StringBuilder builder = new StringBuilder(); - builder.append(getTypeName()); - - final String subtype = getSubtypeName(); - if (!TextUtils.isEmpty(subtype)) { - builder.append("[").append(subtype).append("]"); - } - - builder.append(" "); - builder.append(mDetailedState); - if (mIsRoaming) { - builder.append(" ROAMING"); - } - if (mExtraInfo != null) { - builder.append(" extra: ").append(mExtraInfo); - } - return builder.toString(); - } - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - synchronized (this) { - dest.writeInt(mNetworkType); - dest.writeInt(mSubtype); - dest.writeString(mTypeName); - dest.writeString(mSubtypeName); - dest.writeString(mState.name()); - dest.writeString(mDetailedState.name()); - dest.writeInt(mIsFailover ? 1 : 0); - dest.writeInt(mIsAvailable ? 1 : 0); - dest.writeInt(mIsRoaming ? 1 : 0); - dest.writeString(mReason); - dest.writeString(mExtraInfo); - } - } - - public static final @android.annotation.NonNull Creator<NetworkInfo> CREATOR = new Creator<NetworkInfo>() { - @Override - public NetworkInfo createFromParcel(Parcel in) { - int netType = in.readInt(); - int subtype = in.readInt(); - String typeName = in.readString(); - String subtypeName = in.readString(); - NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName); - netInfo.mState = State.valueOf(in.readString()); - netInfo.mDetailedState = DetailedState.valueOf(in.readString()); - netInfo.mIsFailover = in.readInt() != 0; - netInfo.mIsAvailable = in.readInt() != 0; - netInfo.mIsRoaming = in.readInt() != 0; - netInfo.mReason = in.readString(); - netInfo.mExtraInfo = in.readString(); - return netInfo; - } - - @Override - public NetworkInfo[] newArray(int size) { - return new NetworkInfo[size]; - } - }; -} diff --git a/core/java/android/net/NetworkProvider.java b/core/java/android/net/NetworkProvider.java deleted file mode 100644 index 14cb51c85d06..000000000000 --- a/core/java/android/net/NetworkProvider.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.content.Context; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.Messenger; -import android.util.Log; - -/** - * Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device - * to networks and makes them available to the core network stack by creating - * {@link NetworkAgent}s. The networks can then provide connectivity to apps and can be interacted - * with via networking APIs such as {@link ConnectivityManager}. - * - * Subclasses should implement {@link #onNetworkRequested} and {@link #onNetworkRequestWithdrawn} - * to receive {@link NetworkRequest}s sent by the system and by apps. A network that is not the - * best (highest-scoring) network for any request is generally not used by the system, and torn - * down. - * - * @hide - */ -@SystemApi -public class NetworkProvider { - /** - * {@code providerId} value that indicates the absence of a provider. It is the providerId of - * any NetworkProvider that is not currently registered, and of any NetworkRequest that is not - * currently being satisfied by a network. - */ - public static final int ID_NONE = -1; - - /** - * The first providerId value that will be allocated. - * @hide only used by ConnectivityService. - */ - public static final int FIRST_PROVIDER_ID = 1; - - /** @hide only used by ConnectivityService */ - public static final int CMD_REQUEST_NETWORK = 1; - /** @hide only used by ConnectivityService */ - public static final int CMD_CANCEL_REQUEST = 2; - - private final Messenger mMessenger; - private final String mName; - private final Context mContext; - - private int mProviderId = ID_NONE; - - /** - * Constructs a new NetworkProvider. - * - * @param looper the Looper on which to run {@link #onNetworkRequested} and - * {@link #onNetworkRequestWithdrawn}. - * @param name the name of the listener, used only for debugging. - * - * @hide - */ - @SystemApi - public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) { - Handler handler = new Handler(looper) { - @Override - public void handleMessage(Message m) { - switch (m.what) { - case CMD_REQUEST_NETWORK: - onNetworkRequested((NetworkRequest) m.obj, m.arg1, m.arg2); - break; - case CMD_CANCEL_REQUEST: - onNetworkRequestWithdrawn((NetworkRequest) m.obj); - break; - default: - Log.e(mName, "Unhandled message: " + m.what); - } - } - }; - mContext = context; - mMessenger = new Messenger(handler); - mName = name; - } - - // TODO: consider adding a register() method so ConnectivityManager does not need to call this. - /** @hide */ - public @Nullable Messenger getMessenger() { - return mMessenger; - } - - /** @hide */ - public @NonNull String getName() { - return mName; - } - - /** - * Returns the ID of this provider. This is known only once the provider is registered via - * {@link ConnectivityManager#registerNetworkProvider()}, otherwise the ID is {@link #ID_NONE}. - * This ID must be used when registering any {@link NetworkAgent}s. - */ - public int getProviderId() { - return mProviderId; - } - - /** @hide */ - public void setProviderId(int providerId) { - mProviderId = providerId; - } - - /** - * Called when a NetworkRequest is received. The request may be a new request or an existing - * request with a different score. - * - * @param request the NetworkRequest being received - * @param score the score of the network currently satisfying the request, or 0 if none. - * @param providerId the ID of the provider that created the network currently satisfying this - * request, or {@link #ID_NONE} if none. - * - * @hide - */ - @SystemApi - public void onNetworkRequested(@NonNull NetworkRequest request, - @IntRange(from = 0, to = 99) int score, int providerId) {} - - /** - * Called when a NetworkRequest is withdrawn. - * @hide - */ - @SystemApi - public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {} - - /** - * Asserts that no provider will ever be able to satisfy the specified request. The provider - * must only call this method if it knows that it is the only provider on the system capable of - * satisfying this request, and that the request cannot be satisfied. The application filing the - * request will receive an {@link NetworkCallback#onUnavailable()} callback. - * - * @param request the request that permanently cannot be fulfilled - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) - public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { - ConnectivityManager.from(mContext).declareNetworkRequestUnfulfillable(request); - } -} diff --git a/core/java/android/net/NetworkRequest.aidl b/core/java/android/net/NetworkRequest.aidl deleted file mode 100644 index 508defc6b497..000000000000 --- a/core/java/android/net/NetworkRequest.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) 2014, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -parcelable NetworkRequest; - diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java deleted file mode 100644 index 04011fc6816e..000000000000 --- a/core/java/android/net/NetworkRequest.java +++ /dev/null @@ -1,582 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.compat.annotation.UnsupportedAppUsage; -import android.net.NetworkCapabilities.NetCapability; -import android.net.NetworkCapabilities.Transport; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.Process; -import android.text.TextUtils; -import android.util.proto.ProtoOutputStream; - -import java.util.Objects; -import java.util.Set; - -/** - * Defines a request for a network, made through {@link NetworkRequest.Builder} and used - * to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes - * via {@link ConnectivityManager#registerNetworkCallback}. - */ -public class NetworkRequest implements Parcelable { - /** - * The first requestId value that will be allocated. - * @hide only used by ConnectivityService. - */ - public static final int FIRST_REQUEST_ID = 1; - - /** - * The requestId value that represents the absence of a request. - * @hide only used by ConnectivityService. - */ - public static final int REQUEST_ID_NONE = -1; - - /** - * The {@link NetworkCapabilities} that define this request. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public final @NonNull NetworkCapabilities networkCapabilities; - - /** - * Identifies the request. NetworkRequests should only be constructed by - * the Framework and given out to applications as tokens to be used to identify - * the request. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public final int requestId; - - /** - * Set for legacy requests and the default. Set to TYPE_NONE for none. - * Causes CONNECTIVITY_ACTION broadcasts to be sent. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - public final int legacyType; - - /** - * A NetworkRequest as used by the system can be one of the following types: - * - * - LISTEN, for which the framework will issue callbacks about any - * and all networks that match the specified NetworkCapabilities, - * - * - REQUEST, capable of causing a specific network to be created - * first (e.g. a telephony DUN request), the framework will issue - * callbacks about the single, highest scoring current network - * (if any) that matches the specified NetworkCapabilities, or - * - * - TRACK_DEFAULT, a hybrid of the two designed such that the - * framework will issue callbacks for the single, highest scoring - * current network (if any) that matches the capabilities of the - * default Internet request (mDefaultRequest), but which cannot cause - * the framework to either create or retain the existence of any - * specific network. Note that from the point of view of the request - * matching code, TRACK_DEFAULT is identical to REQUEST: its special - * behaviour is not due to different semantics, but to the fact that - * the system will only ever create a TRACK_DEFAULT with capabilities - * that are identical to the default request's capabilities, thus - * causing it to share fate in every way with the default request. - * - * - BACKGROUND_REQUEST, like REQUEST but does not cause any networks - * to retain the NET_CAPABILITY_FOREGROUND capability. A network with - * no foreground requests is in the background. A network that has - * one or more background requests and loses its last foreground - * request to a higher-scoring network will not go into the - * background immediately, but will linger and go into the background - * after the linger timeout. - * - * - The value NONE is used only by applications. When an application - * creates a NetworkRequest, it does not have a type; the type is set - * by the system depending on the method used to file the request - * (requestNetwork, registerNetworkCallback, etc.). - * - * @hide - */ - public static enum Type { - NONE, - LISTEN, - TRACK_DEFAULT, - REQUEST, - BACKGROUND_REQUEST, - }; - - /** - * The type of the request. This is only used by the system and is always NONE elsewhere. - * - * @hide - */ - public final Type type; - - /** - * @hide - */ - public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId, Type type) { - if (nc == null) { - throw new NullPointerException(); - } - requestId = rId; - networkCapabilities = nc; - this.legacyType = legacyType; - this.type = type; - } - - /** - * @hide - */ - public NetworkRequest(NetworkRequest that) { - networkCapabilities = new NetworkCapabilities(that.networkCapabilities); - requestId = that.requestId; - this.legacyType = that.legacyType; - this.type = that.type; - } - - /** - * Builder used to create {@link NetworkRequest} objects. Specify the Network features - * needed in terms of {@link NetworkCapabilities} features - */ - public static class Builder { - private final NetworkCapabilities mNetworkCapabilities; - - /** - * Default constructor for Builder. - */ - public Builder() { - // By default, restrict this request to networks available to this app. - // Apps can rescind this restriction, but ConnectivityService will enforce - // it for apps that do not have the NETWORK_SETTINGS permission. - mNetworkCapabilities = new NetworkCapabilities(); - mNetworkCapabilities.setSingleUid(Process.myUid()); - } - - /** - * Build {@link NetworkRequest} give the current set of capabilities. - */ - public NetworkRequest build() { - // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED - // when later an unrestricted capability could be added to mNetworkCapabilities, in - // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which - // maybeMarkCapabilitiesRestricted() doesn't add back. - final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities); - nc.maybeMarkCapabilitiesRestricted(); - return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE, - ConnectivityManager.REQUEST_ID_UNSET, Type.NONE); - } - - /** - * Add the given capability requirement to this builder. These represent - * the requested network's required capabilities. Note that when searching - * for a network to satisfy a request, all capabilities requested must be - * satisfied. - * - * @param capability The capability to add. - * @return The builder to facilitate chaining - * {@code builder.addCapability(...).addCapability();}. - */ - public Builder addCapability(@NetworkCapabilities.NetCapability int capability) { - mNetworkCapabilities.addCapability(capability); - return this; - } - - /** - * Removes (if found) the given capability from this builder instance. - * - * @param capability The capability to remove. - * @return The builder to facilitate chaining. - */ - public Builder removeCapability(@NetworkCapabilities.NetCapability int capability) { - mNetworkCapabilities.removeCapability(capability); - return this; - } - - /** - * Set the {@code NetworkCapabilities} for this builder instance, - * overriding any capabilities that had been previously set. - * - * @param nc The superseding {@code NetworkCapabilities} instance. - * @return The builder to facilitate chaining. - * @hide - */ - public Builder setCapabilities(NetworkCapabilities nc) { - mNetworkCapabilities.set(nc); - return this; - } - - /** - * Set the watched UIDs for this request. This will be reset and wiped out unless - * the calling app holds the CHANGE_NETWORK_STATE permission. - * - * @param uids The watched UIDs as a set of UidRanges, or null for everything. - * @return The builder to facilitate chaining. - * @hide - */ - public Builder setUids(Set<UidRange> uids) { - mNetworkCapabilities.setUids(uids); - return this; - } - - /** - * Add a capability that must not exist in the requested network. - * <p> - * If the capability was previously added to the list of required capabilities (for - * example, it was there by default or added using {@link #addCapability(int)} method), then - * it will be removed from the list of required capabilities as well. - * - * @see #addCapability(int) - * - * @param capability The capability to add to unwanted capability list. - * @return The builder to facilitate chaining. - * - * @hide - */ - public Builder addUnwantedCapability(@NetworkCapabilities.NetCapability int capability) { - mNetworkCapabilities.addUnwantedCapability(capability); - return this; - } - - /** - * Completely clears all the {@code NetworkCapabilities} from this builder instance, - * removing even the capabilities that are set by default when the object is constructed. - * - * @return The builder to facilitate chaining. - */ - @NonNull - public Builder clearCapabilities() { - mNetworkCapabilities.clearAll(); - return this; - } - - /** - * Adds the given transport requirement to this builder. These represent - * the set of allowed transports for the request. Only networks using one - * of these transports will satisfy the request. If no particular transports - * are required, none should be specified here. - * - * @param transportType The transport type to add. - * @return The builder to facilitate chaining. - */ - public Builder addTransportType(@NetworkCapabilities.Transport int transportType) { - mNetworkCapabilities.addTransportType(transportType); - return this; - } - - /** - * Removes (if found) the given transport from this builder instance. - * - * @param transportType The transport type to remove. - * @return The builder to facilitate chaining. - */ - public Builder removeTransportType(@NetworkCapabilities.Transport int transportType) { - mNetworkCapabilities.removeTransportType(transportType); - return this; - } - - /** - * @hide - */ - public Builder setLinkUpstreamBandwidthKbps(int upKbps) { - mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps); - return this; - } - /** - * @hide - */ - public Builder setLinkDownstreamBandwidthKbps(int downKbps) { - mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps); - return this; - } - - /** - * Sets the optional bearer specific network specifier. - * This has no meaning if a single transport is also not specified, so calling - * this without a single transport set will generate an exception, as will - * subsequently adding or removing transports after this is set. - * </p> - * If the {@code networkSpecifier} is provided, it shall be interpreted as follows: - * <ul> - * <li>If the specifier can be parsed as an integer, it will be treated as a - * {@link android.net TelephonyNetworkSpecifier}, and the provided integer will be - * interpreted as a SubscriptionId. - * <li>If the value is an ethernet interface name, it will be treated as such. - * <li>For all other cases, the behavior is undefined. - * </ul> - * - * @param networkSpecifier A {@code String} of either a SubscriptionId in cellular - * network request or an ethernet interface name in ethernet - * network request. - * - * @deprecated Use {@link #setNetworkSpecifier(NetworkSpecifier)} instead. - */ - @Deprecated - public Builder setNetworkSpecifier(String networkSpecifier) { - try { - int subId = Integer.parseInt(networkSpecifier); - return setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() - .setSubscriptionId(subId).build()); - } catch (NumberFormatException nfe) { - // A StringNetworkSpecifier does not accept null or empty ("") strings. When network - // specifiers were strings a null string and an empty string were considered - // equivalent. Hence no meaning is attached to a null or empty ("") string. - return setNetworkSpecifier(TextUtils.isEmpty(networkSpecifier) ? null - : new StringNetworkSpecifier(networkSpecifier)); - } - } - - /** - * Sets the optional bearer specific network specifier. - * This has no meaning if a single transport is also not specified, so calling - * this without a single transport set will generate an exception, as will - * subsequently adding or removing transports after this is set. - * </p> - * - * @param networkSpecifier A concrete, parcelable framework class that extends - * NetworkSpecifier. - */ - public Builder setNetworkSpecifier(NetworkSpecifier networkSpecifier) { - if (networkSpecifier instanceof MatchAllNetworkSpecifier) { - throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted"); - } - mNetworkCapabilities.setNetworkSpecifier(networkSpecifier); - return this; - } - - /** - * Sets the signal strength. This is a signed integer, with higher values indicating a - * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same - * RSSI units reported by WifiManager. - * <p> - * Note that when used to register a network callback, this specifies the minimum acceptable - * signal strength. When received as the state of an existing network it specifies the - * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when - * received and has no effect when requesting a callback. - * - * <p>This method requires the caller to hold the - * {@link android.Manifest.permission#NETWORK_SIGNAL_STRENGTH_WAKEUP} permission - * - * @param signalStrength the bearer-specific signal strength. - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) - public @NonNull Builder setSignalStrength(int signalStrength) { - mNetworkCapabilities.setSignalStrength(signalStrength); - return this; - } - } - - // implement the Parcelable interface - public int describeContents() { - return 0; - } - public void writeToParcel(Parcel dest, int flags) { - networkCapabilities.writeToParcel(dest, flags); - dest.writeInt(legacyType); - dest.writeInt(requestId); - dest.writeString(type.name()); - } - - public static final @android.annotation.NonNull Creator<NetworkRequest> CREATOR = - new Creator<NetworkRequest>() { - public NetworkRequest createFromParcel(Parcel in) { - NetworkCapabilities nc = NetworkCapabilities.CREATOR.createFromParcel(in); - int legacyType = in.readInt(); - int requestId = in.readInt(); - Type type = Type.valueOf(in.readString()); // IllegalArgumentException if invalid. - NetworkRequest result = new NetworkRequest(nc, legacyType, requestId, type); - return result; - } - public NetworkRequest[] newArray(int size) { - return new NetworkRequest[size]; - } - }; - - /** - * Returns true iff. this NetworkRequest is of type LISTEN. - * - * @hide - */ - public boolean isListen() { - return type == Type.LISTEN; - } - - /** - * Returns true iff. the contained NetworkRequest is one that: - * - * - should be associated with at most one satisfying network - * at a time; - * - * - should cause a network to be kept up, but not necessarily in - * the foreground, if it is the best network which can satisfy the - * NetworkRequest. - * - * For full detail of how isRequest() is used for pairing Networks with - * NetworkRequests read rematchNetworkAndRequests(). - * - * @hide - */ - public boolean isRequest() { - return isForegroundRequest() || isBackgroundRequest(); - } - - /** - * Returns true iff. the contained NetworkRequest is one that: - * - * - should be associated with at most one satisfying network - * at a time; - * - * - should cause a network to be kept up and in the foreground if - * it is the best network which can satisfy the NetworkRequest. - * - * For full detail of how isRequest() is used for pairing Networks with - * NetworkRequests read rematchNetworkAndRequests(). - * - * @hide - */ - public boolean isForegroundRequest() { - return type == Type.TRACK_DEFAULT || type == Type.REQUEST; - } - - /** - * Returns true iff. this NetworkRequest is of type BACKGROUND_REQUEST. - * - * @hide - */ - public boolean isBackgroundRequest() { - return type == Type.BACKGROUND_REQUEST; - } - - /** - * @see Builder#addCapability(int) - */ - public boolean hasCapability(@NetCapability int capability) { - return networkCapabilities.hasCapability(capability); - } - - /** - * @see Builder#addUnwantedCapability(int) - * - * @hide - */ - public boolean hasUnwantedCapability(@NetCapability int capability) { - return networkCapabilities.hasUnwantedCapability(capability); - } - - /** - * Returns true if and only if the capabilities requested in this NetworkRequest are satisfied - * by the provided {@link NetworkCapabilities}. - * - * @param nc Capabilities that should satisfy this NetworkRequest. null capabilities do not - * satisfy any request. - */ - public boolean canBeSatisfiedBy(@Nullable NetworkCapabilities nc) { - return networkCapabilities.satisfiedByNetworkCapabilities(nc); - } - - /** - * @see Builder#addTransportType(int) - */ - public boolean hasTransport(@Transport int transportType) { - return networkCapabilities.hasTransport(transportType); - } - - /** - * @see Builder#setNetworkSpecifier(NetworkSpecifier) - */ - @Nullable - public NetworkSpecifier getNetworkSpecifier() { - return networkCapabilities.getNetworkSpecifier(); - } - - /** - * @return the uid of the app making the request. - * - * Note: This could return {@link Process#INVALID_UID} if the {@link NetworkRequest} object was - * not obtained from {@link ConnectivityManager}. - * @hide - */ - @SystemApi - public int getRequestorUid() { - return networkCapabilities.getRequestorUid(); - } - - /** - * @return the package name of the app making the request. - * - * Note: This could return {@code null} if the {@link NetworkRequest} object was not obtained - * from {@link ConnectivityManager}. - * @hide - */ - @SystemApi - @Nullable - public String getRequestorPackageName() { - return networkCapabilities.getRequestorPackageName(); - } - - public String toString() { - return "NetworkRequest [ " + type + " id=" + requestId + - (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") + - ", " + networkCapabilities.toString() + " ]"; - } - - private int typeToProtoEnum(Type t) { - switch (t) { - case NONE: - return NetworkRequestProto.TYPE_NONE; - case LISTEN: - return NetworkRequestProto.TYPE_LISTEN; - case TRACK_DEFAULT: - return NetworkRequestProto.TYPE_TRACK_DEFAULT; - case REQUEST: - return NetworkRequestProto.TYPE_REQUEST; - case BACKGROUND_REQUEST: - return NetworkRequestProto.TYPE_BACKGROUND_REQUEST; - default: - return NetworkRequestProto.TYPE_UNKNOWN; - } - } - - /** @hide */ - public void dumpDebug(ProtoOutputStream proto, long fieldId) { - final long token = proto.start(fieldId); - - proto.write(NetworkRequestProto.TYPE, typeToProtoEnum(type)); - proto.write(NetworkRequestProto.REQUEST_ID, requestId); - proto.write(NetworkRequestProto.LEGACY_TYPE, legacyType); - networkCapabilities.dumpDebug(proto, NetworkRequestProto.NETWORK_CAPABILITIES); - - proto.end(token); - } - - public boolean equals(Object obj) { - if (obj instanceof NetworkRequest == false) return false; - NetworkRequest that = (NetworkRequest)obj; - return (that.legacyType == this.legacyType && - that.requestId == this.requestId && - that.type == this.type && - Objects.equals(that.networkCapabilities, this.networkCapabilities)); - } - - public int hashCode() { - return Objects.hash(requestId, legacyType, networkCapabilities, type); - } -} diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java deleted file mode 100644 index 8be4af7b1396..000000000000 --- a/core/java/android/net/NetworkUtils.java +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; -import android.system.ErrnoException; -import android.util.Log; -import android.util.Pair; - -import com.android.net.module.util.Inet4AddressUtils; - -import java.io.FileDescriptor; -import java.math.BigInteger; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.Locale; -import java.util.TreeSet; - -/** - * Native methods for managing network interfaces. - * - * {@hide} - */ -public class NetworkUtils { - - private static final String TAG = "NetworkUtils"; - - /** - * Attaches a socket filter that drops all of incoming packets. - * @param fd the socket's {@link FileDescriptor}. - */ - public static native void attachDropAllBPFFilter(FileDescriptor fd) throws SocketException; - - /** - * Detaches a socket filter. - * @param fd the socket's {@link FileDescriptor}. - */ - public static native void detachBPFFilter(FileDescriptor fd) throws SocketException; - - /** - * Binds the current process to the network designated by {@code netId}. All sockets created - * in the future (and not explicitly bound via a bound {@link SocketFactory} (see - * {@link Network#getSocketFactory}) will be bound to this network. Note that if this - * {@code Network} ever disconnects all sockets created in this way will cease to work. This - * is by design so an application doesn't accidentally use sockets it thinks are still bound to - * a particular {@code Network}. Passing NETID_UNSET clears the binding. - */ - public native static boolean bindProcessToNetwork(int netId); - - /** - * Return the netId last passed to {@link #bindProcessToNetwork}, or NETID_UNSET if - * {@link #unbindProcessToNetwork} has been called since {@link #bindProcessToNetwork}. - */ - public native static int getBoundNetworkForProcess(); - - /** - * Binds host resolutions performed by this process to the network designated by {@code netId}. - * {@link #bindProcessToNetwork} takes precedence over this setting. Passing NETID_UNSET clears - * the binding. - * - * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature(). - */ - @Deprecated - public native static boolean bindProcessToNetworkForHostResolution(int netId); - - /** - * Explicitly binds {@code fd} to the network designated by {@code netId}. This - * overrides any binding via {@link #bindProcessToNetwork}. - * @return 0 on success or negative errno on failure. - */ - public static native int bindSocketToNetwork(FileDescriptor fd, int netId); - - /** - * Protect {@code fd} from VPN connections. After protecting, data sent through - * this socket will go directly to the underlying network, so its traffic will not be - * forwarded through the VPN. - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static native boolean protectFromVpn(FileDescriptor fd); - - /** - * Protect {@code socketfd} from VPN connections. After protecting, data sent through - * this socket will go directly to the underlying network, so its traffic will not be - * forwarded through the VPN. - */ - public native static boolean protectFromVpn(int socketfd); - - /** - * Determine if {@code uid} can access network designated by {@code netId}. - * @return {@code true} if {@code uid} can access network, {@code false} otherwise. - */ - public native static boolean queryUserAccess(int uid, int netId); - - /** - * DNS resolver series jni method. - * Issue the query {@code msg} on the network designated by {@code netId}. - * {@code flags} is an additional config to control actual querying behavior. - * @return a file descriptor to watch for read events - */ - public static native FileDescriptor resNetworkSend( - int netId, byte[] msg, int msglen, int flags) throws ErrnoException; - - /** - * DNS resolver series jni method. - * Look up the {@code nsClass} {@code nsType} Resource Record (RR) associated - * with Domain Name {@code dname} on the network designated by {@code netId}. - * {@code flags} is an additional config to control actual querying behavior. - * @return a file descriptor to watch for read events - */ - public static native FileDescriptor resNetworkQuery( - int netId, String dname, int nsClass, int nsType, int flags) throws ErrnoException; - - /** - * DNS resolver series jni method. - * Read a result for the query associated with the {@code fd}. - * @return DnsResponse containing blob answer and rcode - */ - public static native DnsResolver.DnsResponse resNetworkResult(FileDescriptor fd) - throws ErrnoException; - - /** - * DNS resolver series jni method. - * Attempts to cancel the in-progress query associated with the {@code fd}. - */ - public static native void resNetworkCancel(FileDescriptor fd); - - /** - * DNS resolver series jni method. - * Attempts to get network which resolver will use if no network is explicitly selected. - */ - public static native Network getDnsNetwork() throws ErrnoException; - - /** - * Get the tcp repair window associated with the {@code fd}. - * - * @param fd the tcp socket's {@link FileDescriptor}. - * @return a {@link TcpRepairWindow} object indicates tcp window size. - */ - public static native TcpRepairWindow getTcpRepairWindow(FileDescriptor fd) - throws ErrnoException; - - /** - * @see Inet4AddressUtils#intToInet4AddressHTL(int) - * @deprecated Use either {@link Inet4AddressUtils#intToInet4AddressHTH(int)} - * or {@link Inet4AddressUtils#intToInet4AddressHTL(int)} - */ - @Deprecated - @UnsupportedAppUsage - public static InetAddress intToInetAddress(int hostAddress) { - return Inet4AddressUtils.intToInet4AddressHTL(hostAddress); - } - - /** - * @see Inet4AddressUtils#inet4AddressToIntHTL(Inet4Address) - * @deprecated Use either {@link Inet4AddressUtils#inet4AddressToIntHTH(Inet4Address)} - * or {@link Inet4AddressUtils#inet4AddressToIntHTL(Inet4Address)} - */ - @Deprecated - public static int inetAddressToInt(Inet4Address inetAddr) - throws IllegalArgumentException { - return Inet4AddressUtils.inet4AddressToIntHTL(inetAddr); - } - - /** - * @see Inet4AddressUtils#prefixLengthToV4NetmaskIntHTL(int) - * @deprecated Use either {@link Inet4AddressUtils#prefixLengthToV4NetmaskIntHTH(int)} - * or {@link Inet4AddressUtils#prefixLengthToV4NetmaskIntHTL(int)} - */ - @Deprecated - @UnsupportedAppUsage - public static int prefixLengthToNetmaskInt(int prefixLength) - throws IllegalArgumentException { - return Inet4AddressUtils.prefixLengthToV4NetmaskIntHTL(prefixLength); - } - - /** - * Convert a IPv4 netmask integer to a prefix length - * @param netmask as an integer (0xff000000 for a /8 subnet) - * @return the network prefix length - */ - public static int netmaskIntToPrefixLength(int netmask) { - return Integer.bitCount(netmask); - } - - /** - * Convert an IPv4 netmask to a prefix length, checking that the netmask is contiguous. - * @param netmask as a {@code Inet4Address}. - * @return the network prefix length - * @throws IllegalArgumentException the specified netmask was not contiguous. - * @hide - * @deprecated use {@link Inet4AddressUtils#netmaskToPrefixLength(Inet4Address)} - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @Deprecated - public static int netmaskToPrefixLength(Inet4Address netmask) { - // This is only here because some apps seem to be using it (@UnsupportedAppUsage). - return Inet4AddressUtils.netmaskToPrefixLength(netmask); - } - - - /** - * Create an InetAddress from a string where the string must be a standard - * representation of a V4 or V6 address. Avoids doing a DNS lookup on failure - * but it will throw an IllegalArgumentException in that case. - * @param addrString - * @return the InetAddress - * @hide - * @deprecated Use {@link InetAddresses#parseNumericAddress(String)}, if possible. - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - @Deprecated - public static InetAddress numericToInetAddress(String addrString) - throws IllegalArgumentException { - return InetAddress.parseNumericAddress(addrString); - } - - /** - * Masks a raw IP address byte array with the specified prefix length. - */ - public static void maskRawAddress(byte[] array, int prefixLength) { - if (prefixLength < 0 || prefixLength > array.length * 8) { - throw new RuntimeException("IP address with " + array.length + - " bytes has invalid prefix length " + prefixLength); - } - - int offset = prefixLength / 8; - int remainder = prefixLength % 8; - byte mask = (byte)(0xFF << (8 - remainder)); - - if (offset < array.length) array[offset] = (byte)(array[offset] & mask); - - offset++; - - for (; offset < array.length; offset++) { - array[offset] = 0; - } - } - - /** - * Get InetAddress masked with prefixLength. Will never return null. - * @param address the IP address to mask with - * @param prefixLength the prefixLength used to mask the IP - */ - public static InetAddress getNetworkPart(InetAddress address, int prefixLength) { - byte[] array = address.getAddress(); - maskRawAddress(array, prefixLength); - - InetAddress netPart = null; - try { - netPart = InetAddress.getByAddress(array); - } catch (UnknownHostException e) { - throw new RuntimeException("getNetworkPart error - " + e.toString()); - } - return netPart; - } - - /** - * Returns the implicit netmask of an IPv4 address, as was the custom before 1993. - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static int getImplicitNetmask(Inet4Address address) { - // Only here because it seems to be used by apps - return Inet4AddressUtils.getImplicitNetmask(address); - } - - /** - * Utility method to parse strings such as "192.0.2.5/24" or "2001:db8::cafe:d00d/64". - * @hide - */ - public static Pair<InetAddress, Integer> parseIpAndMask(String ipAndMaskString) { - InetAddress address = null; - int prefixLength = -1; - try { - String[] pieces = ipAndMaskString.split("/", 2); - prefixLength = Integer.parseInt(pieces[1]); - address = InetAddress.parseNumericAddress(pieces[0]); - } catch (NullPointerException e) { // Null string. - } catch (ArrayIndexOutOfBoundsException e) { // No prefix length. - } catch (NumberFormatException e) { // Non-numeric prefix. - } catch (IllegalArgumentException e) { // Invalid IP address. - } - - if (address == null || prefixLength == -1) { - throw new IllegalArgumentException("Invalid IP address and mask " + ipAndMaskString); - } - - return new Pair<InetAddress, Integer>(address, prefixLength); - } - - /** - * Convert a 32 char hex string into a Inet6Address. - * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be - * made into an Inet6Address - * @param addrHexString a 32 character hex string representing an IPv6 addr - * @return addr an InetAddress representation for the string - */ - public static InetAddress hexToInet6Address(String addrHexString) - throws IllegalArgumentException { - try { - return numericToInetAddress(String.format(Locale.US, "%s:%s:%s:%s:%s:%s:%s:%s", - addrHexString.substring(0,4), addrHexString.substring(4,8), - addrHexString.substring(8,12), addrHexString.substring(12,16), - addrHexString.substring(16,20), addrHexString.substring(20,24), - addrHexString.substring(24,28), addrHexString.substring(28,32))); - } catch (Exception e) { - Log.e("NetworkUtils", "error in hexToInet6Address(" + addrHexString + "): " + e); - throw new IllegalArgumentException(e); - } - } - - /** - * Trim leading zeros from IPv4 address strings - * Our base libraries will interpret that as octel.. - * Must leave non v4 addresses and host names alone. - * For example, 192.168.000.010 -> 192.168.0.10 - * TODO - fix base libraries and remove this function - * @param addr a string representing an ip addr - * @return a string propertly trimmed - */ - @UnsupportedAppUsage - public static String trimV4AddrZeros(String addr) { - if (addr == null) return null; - String[] octets = addr.split("\\."); - if (octets.length != 4) return addr; - StringBuilder builder = new StringBuilder(16); - String result = null; - for (int i = 0; i < 4; i++) { - try { - if (octets[i].length() > 3) return addr; - builder.append(Integer.parseInt(octets[i])); - } catch (NumberFormatException e) { - return addr; - } - if (i < 3) builder.append('.'); - } - result = builder.toString(); - return result; - } - - /** - * Returns a prefix set without overlaps. - * - * This expects the src set to be sorted from shorter to longer. Results are undefined - * failing this condition. The returned prefix set is sorted in the same order as the - * passed set, with the same comparator. - */ - private static TreeSet<IpPrefix> deduplicatePrefixSet(final TreeSet<IpPrefix> src) { - final TreeSet<IpPrefix> dst = new TreeSet<>(src.comparator()); - // Prefixes match addresses that share their upper part up to their length, therefore - // the only kind of possible overlap in two prefixes is strict inclusion of the longer - // (more restrictive) in the shorter (including equivalence if they have the same - // length). - // Because prefixes in the src set are sorted from shorter to longer, deduplicating - // is done by simply iterating in order, and not adding any longer prefix that is - // already covered by a shorter one. - newPrefixes: - for (IpPrefix newPrefix : src) { - for (IpPrefix existingPrefix : dst) { - if (existingPrefix.containsPrefix(newPrefix)) { - continue newPrefixes; - } - } - dst.add(newPrefix); - } - return dst; - } - - /** - * Returns how many IPv4 addresses match any of the prefixes in the passed ordered set. - * - * Obviously this returns an integral value between 0 and 2**32. - * The behavior is undefined if any of the prefixes is not an IPv4 prefix or if the - * set is not ordered smallest prefix to longer prefix. - * - * @param prefixes the set of prefixes, ordered by length - */ - public static long routedIPv4AddressCount(final TreeSet<IpPrefix> prefixes) { - long routedIPCount = 0; - for (final IpPrefix prefix : deduplicatePrefixSet(prefixes)) { - if (!prefix.isIPv4()) { - Log.wtf(TAG, "Non-IPv4 prefix in routedIPv4AddressCount"); - } - int rank = 32 - prefix.getPrefixLength(); - routedIPCount += 1L << rank; - } - return routedIPCount; - } - - /** - * Returns how many IPv6 addresses match any of the prefixes in the passed ordered set. - * - * This returns a BigInteger between 0 and 2**128. - * The behavior is undefined if any of the prefixes is not an IPv6 prefix or if the - * set is not ordered smallest prefix to longer prefix. - */ - public static BigInteger routedIPv6AddressCount(final TreeSet<IpPrefix> prefixes) { - BigInteger routedIPCount = BigInteger.ZERO; - for (final IpPrefix prefix : deduplicatePrefixSet(prefixes)) { - if (!prefix.isIPv6()) { - Log.wtf(TAG, "Non-IPv6 prefix in routedIPv6AddressCount"); - } - int rank = 128 - prefix.getPrefixLength(); - routedIPCount = routedIPCount.add(BigInteger.ONE.shiftLeft(rank)); - } - return routedIPCount; - } - -} diff --git a/core/java/android/net/PacProxySelector.java b/core/java/android/net/PacProxySelector.java deleted file mode 100644 index 326943a27d4e..000000000000 --- a/core/java/android/net/PacProxySelector.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.os.ServiceManager; -import android.util.Log; - -import com.android.net.IProxyService; - -import com.google.android.collect.Lists; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.Proxy; -import java.net.Proxy.Type; -import java.net.ProxySelector; -import java.net.SocketAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; - -/** - * @hide - */ -public class PacProxySelector extends ProxySelector { - private static final String TAG = "PacProxySelector"; - public static final String PROXY_SERVICE = "com.android.net.IProxyService"; - private static final String SOCKS = "SOCKS "; - private static final String PROXY = "PROXY "; - - private IProxyService mProxyService; - private final List<Proxy> mDefaultList; - - public PacProxySelector() { - mProxyService = IProxyService.Stub.asInterface( - ServiceManager.getService(PROXY_SERVICE)); - if (mProxyService == null) { - // Added because of b10267814 where mako is restarting. - Log.e(TAG, "PacProxyInstaller: no proxy service"); - } - mDefaultList = Lists.newArrayList(java.net.Proxy.NO_PROXY); - } - - @Override - public List<Proxy> select(URI uri) { - if (mProxyService == null) { - mProxyService = IProxyService.Stub.asInterface( - ServiceManager.getService(PROXY_SERVICE)); - } - if (mProxyService == null) { - Log.e(TAG, "select: no proxy service return NO_PROXY"); - return Lists.newArrayList(java.net.Proxy.NO_PROXY); - } - String response = null; - String urlString; - try { - // Strip path and username/password from URI so it's not visible to PAC script. The - // path often contains credentials the app does not want exposed to a potentially - // malicious PAC script. - if (!"http".equalsIgnoreCase(uri.getScheme())) { - uri = new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), "/", null, null); - } - urlString = uri.toURL().toString(); - } catch (URISyntaxException e) { - urlString = uri.getHost(); - } catch (MalformedURLException e) { - urlString = uri.getHost(); - } - try { - response = mProxyService.resolvePacFile(uri.getHost(), urlString); - } catch (Exception e) { - Log.e(TAG, "Error resolving PAC File", e); - } - if (response == null) { - return mDefaultList; - } - - return parseResponse(response); - } - - private static List<Proxy> parseResponse(String response) { - String[] split = response.split(";"); - List<Proxy> ret = Lists.newArrayList(); - for (String s : split) { - String trimmed = s.trim(); - if (trimmed.equals("DIRECT")) { - ret.add(java.net.Proxy.NO_PROXY); - } else if (trimmed.startsWith(PROXY)) { - Proxy proxy = proxyFromHostPort(Type.HTTP, trimmed.substring(PROXY.length())); - if (proxy != null) { - ret.add(proxy); - } - } else if (trimmed.startsWith(SOCKS)) { - Proxy proxy = proxyFromHostPort(Type.SOCKS, trimmed.substring(SOCKS.length())); - if (proxy != null) { - ret.add(proxy); - } - } - } - if (ret.size() == 0) { - ret.add(java.net.Proxy.NO_PROXY); - } - return ret; - } - - private static Proxy proxyFromHostPort(Proxy.Type type, String hostPortString) { - try { - String[] hostPort = hostPortString.split(":"); - String host = hostPort[0]; - int port = Integer.parseInt(hostPort[1]); - return new Proxy(type, InetSocketAddress.createUnresolved(host, port)); - } catch (NumberFormatException|ArrayIndexOutOfBoundsException e) { - Log.d(TAG, "Unable to parse proxy " + hostPortString + " " + e); - return null; - } - } - - @Override - public void connectFailed(URI uri, SocketAddress address, IOException failure) { - - } - -} diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java deleted file mode 100644 index 03b07e080add..000000000000 --- a/core/java/android/net/Proxy.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.SdkConstant; -import android.annotation.SdkConstant.SdkConstantType; -import android.compat.annotation.UnsupportedAppUsage; -import android.content.Context; -import android.os.Build; -import android.text.TextUtils; -import android.util.Log; - -import com.android.net.module.util.ProxyUtils; - -import java.net.InetSocketAddress; -import java.net.ProxySelector; -import java.net.URI; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A convenience class for accessing the user and default proxy - * settings. - */ -public final class Proxy { - - private static final String TAG = "Proxy"; - - private static final ProxySelector sDefaultProxySelector; - - /** - * Used to notify an app that's caching the proxy that either the default - * connection has changed or any connection's proxy has changed. The new - * proxy should be queried using {@link ConnectivityManager#getDefaultProxy()}. - * - * <p class="note">This is a protected intent that can only be sent by the system - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE"; - /** - * Intent extra included with {@link #PROXY_CHANGE_ACTION} intents. - * It describes the new proxy being used (as a {@link ProxyInfo} object). - * @deprecated Because {@code PROXY_CHANGE_ACTION} is sent whenever the proxy - * for any network on the system changes, applications should always use - * {@link ConnectivityManager#getDefaultProxy()} or - * {@link ConnectivityManager#getLinkProperties(Network)}.{@link LinkProperties#getHttpProxy()} - * to get the proxy for the Network(s) they are using. - */ - @Deprecated - public static final String EXTRA_PROXY_INFO = "android.intent.extra.PROXY_INFO"; - - /** @hide */ - public static final int PROXY_VALID = 0; - /** @hide */ - public static final int PROXY_HOSTNAME_EMPTY = 1; - /** @hide */ - public static final int PROXY_HOSTNAME_INVALID = 2; - /** @hide */ - public static final int PROXY_PORT_EMPTY = 3; - /** @hide */ - public static final int PROXY_PORT_INVALID = 4; - /** @hide */ - public static final int PROXY_EXCLLIST_INVALID = 5; - - private static ConnectivityManager sConnectivityManager = null; - - // Hostname / IP REGEX validation - // Matches blank input, ips, and domain names - private static final String NAME_IP_REGEX = - "[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*"; - - private static final String HOSTNAME_REGEXP = "^$|^" + NAME_IP_REGEX + "$"; - - private static final Pattern HOSTNAME_PATTERN; - - private static final String EXCL_REGEX = - "[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*(\\.[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*)*"; - - private static final String EXCLLIST_REGEXP = "^$|^" + EXCL_REGEX + "(," + EXCL_REGEX + ")*$"; - - private static final Pattern EXCLLIST_PATTERN; - - static { - HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP); - EXCLLIST_PATTERN = Pattern.compile(EXCLLIST_REGEXP); - sDefaultProxySelector = ProxySelector.getDefault(); - } - - /** - * Return the proxy object to be used for the URL given as parameter. - * @param ctx A Context used to get the settings for the proxy host. - * @param url A URL to be accessed. Used to evaluate exclusion list. - * @return Proxy (java.net) object containing the host name. If the - * user did not set a hostname it returns the default host. - * A null value means that no host is to be used. - * {@hide} - */ - @UnsupportedAppUsage - public static final java.net.Proxy getProxy(Context ctx, String url) { - String host = ""; - if ((url != null) && !isLocalHost(host)) { - URI uri = URI.create(url); - ProxySelector proxySelector = ProxySelector.getDefault(); - - List<java.net.Proxy> proxyList = proxySelector.select(uri); - - if (proxyList.size() > 0) { - return proxyList.get(0); - } - } - return java.net.Proxy.NO_PROXY; - } - - - /** - * Return the proxy host set by the user. - * @param ctx A Context used to get the settings for the proxy host. - * @return String containing the host name. If the user did not set a host - * name it returns the default host. A null value means that no - * host is to be used. - * @deprecated Use standard java vm proxy values to find the host, port - * and exclusion list. This call ignores the exclusion list. - */ - @Deprecated - public static final String getHost(Context ctx) { - java.net.Proxy proxy = getProxy(ctx, null); - if (proxy == java.net.Proxy.NO_PROXY) return null; - try { - return ((InetSocketAddress)(proxy.address())).getHostName(); - } catch (Exception e) { - return null; - } - } - - /** - * Return the proxy port set by the user. - * @param ctx A Context used to get the settings for the proxy port. - * @return The port number to use or -1 if no proxy is to be used. - * @deprecated Use standard java vm proxy values to find the host, port - * and exclusion list. This call ignores the exclusion list. - */ - @Deprecated - public static final int getPort(Context ctx) { - java.net.Proxy proxy = getProxy(ctx, null); - if (proxy == java.net.Proxy.NO_PROXY) return -1; - try { - return ((InetSocketAddress)(proxy.address())).getPort(); - } catch (Exception e) { - return -1; - } - } - - /** - * Return the default proxy host specified by the carrier. - * @return String containing the host name or null if there is no proxy for - * this carrier. - * @deprecated Use standard java vm proxy values to find the host, port and - * exclusion list. This call ignores the exclusion list and no - * longer reports only mobile-data apn-based proxy values. - */ - @Deprecated - public static final String getDefaultHost() { - String host = System.getProperty("http.proxyHost"); - if (TextUtils.isEmpty(host)) return null; - return host; - } - - /** - * Return the default proxy port specified by the carrier. - * @return The port number to be used with the proxy host or -1 if there is - * no proxy for this carrier. - * @deprecated Use standard java vm proxy values to find the host, port and - * exclusion list. This call ignores the exclusion list and no - * longer reports only mobile-data apn-based proxy values. - */ - @Deprecated - public static final int getDefaultPort() { - if (getDefaultHost() == null) return -1; - try { - return Integer.parseInt(System.getProperty("http.proxyPort")); - } catch (NumberFormatException e) { - return -1; - } - } - - private static final boolean isLocalHost(String host) { - if (host == null) { - return false; - } - try { - if (host != null) { - if (host.equalsIgnoreCase("localhost")) { - return true; - } - if (InetAddresses.parseNumericAddress(host).isLoopbackAddress()) { - return true; - } - } - } catch (IllegalArgumentException iex) { - } - return false; - } - - /** - * Validate syntax of hostname, port and exclusion list entries - * {@hide} - */ - public static int validate(String hostname, String port, String exclList) { - Matcher match = HOSTNAME_PATTERN.matcher(hostname); - Matcher listMatch = EXCLLIST_PATTERN.matcher(exclList); - - if (!match.matches()) return PROXY_HOSTNAME_INVALID; - - if (!listMatch.matches()) return PROXY_EXCLLIST_INVALID; - - if (hostname.length() > 0 && port.length() == 0) return PROXY_PORT_EMPTY; - - if (port.length() > 0) { - if (hostname.length() == 0) return PROXY_HOSTNAME_EMPTY; - int portVal = -1; - try { - portVal = Integer.parseInt(port); - } catch (NumberFormatException ex) { - return PROXY_PORT_INVALID; - } - if (portVal <= 0 || portVal > 0xFFFF) return PROXY_PORT_INVALID; - } - return PROXY_VALID; - } - - /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final void setHttpProxySystemProperty(ProxyInfo p) { - String host = null; - String port = null; - String exclList = null; - Uri pacFileUrl = Uri.EMPTY; - if (p != null) { - host = p.getHost(); - port = Integer.toString(p.getPort()); - exclList = ProxyUtils.exclusionListAsString(p.getExclusionList()); - pacFileUrl = p.getPacFileUrl(); - } - setHttpProxySystemProperty(host, port, exclList, pacFileUrl); - } - - /** @hide */ - public static final void setHttpProxySystemProperty(String host, String port, String exclList, - Uri pacFileUrl) { - if (exclList != null) exclList = exclList.replace(",", "|"); - if (false) Log.d(TAG, "setHttpProxySystemProperty :"+host+":"+port+" - "+exclList); - if (host != null) { - System.setProperty("http.proxyHost", host); - System.setProperty("https.proxyHost", host); - } else { - System.clearProperty("http.proxyHost"); - System.clearProperty("https.proxyHost"); - } - if (port != null) { - System.setProperty("http.proxyPort", port); - System.setProperty("https.proxyPort", port); - } else { - System.clearProperty("http.proxyPort"); - System.clearProperty("https.proxyPort"); - } - if (exclList != null) { - System.setProperty("http.nonProxyHosts", exclList); - System.setProperty("https.nonProxyHosts", exclList); - } else { - System.clearProperty("http.nonProxyHosts"); - System.clearProperty("https.nonProxyHosts"); - } - if (!Uri.EMPTY.equals(pacFileUrl)) { - ProxySelector.setDefault(new PacProxySelector()); - } else { - ProxySelector.setDefault(sDefaultProxySelector); - } - } -} diff --git a/core/java/android/net/ProxyInfo.aidl b/core/java/android/net/ProxyInfo.aidl deleted file mode 100644 index a5d0c120e747..000000000000 --- a/core/java/android/net/ProxyInfo.aidl +++ /dev/null @@ -1,21 +0,0 @@ -/* -** -** Copyright (C) 2010 The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -package android.net; - -@JavaOnlyStableParcelable parcelable ProxyInfo; - diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java deleted file mode 100644 index c9bca2876b0a..000000000000 --- a/core/java/android/net/ProxyInfo.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.compat.annotation.UnsupportedAppUsage; -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; - -import java.net.InetSocketAddress; -import java.net.URLConnection; -import java.util.List; -import java.util.Locale; - -/** - * Describes a proxy configuration. - * - * Proxy configurations are already integrated within the {@code java.net} and - * Apache HTTP stack. So {@link URLConnection} and Apache's {@code HttpClient} will use - * them automatically. - * - * Other HTTP stacks will need to obtain the proxy info from - * {@link Proxy#PROXY_CHANGE_ACTION} broadcast as the extra {@link Proxy#EXTRA_PROXY_INFO}. - */ -public class ProxyInfo implements Parcelable { - - private final String mHost; - private final int mPort; - private final String mExclusionList; - private final String[] mParsedExclusionList; - private final Uri mPacFileUrl; - - /** - *@hide - */ - public static final String LOCAL_EXCL_LIST = ""; - /** - *@hide - */ - public static final int LOCAL_PORT = -1; - /** - *@hide - */ - public static final String LOCAL_HOST = "localhost"; - - /** - * Constructs a {@link ProxyInfo} object that points at a Direct proxy - * on the specified host and port. - */ - public static ProxyInfo buildDirectProxy(String host, int port) { - return new ProxyInfo(host, port, null); - } - - /** - * Constructs a {@link ProxyInfo} object that points at a Direct proxy - * on the specified host and port. - * - * The proxy will not be used to access any host in exclusion list, exclList. - * - * @param exclList Hosts to exclude using the proxy on connections for. These - * hosts can use wildcards such as *.example.com. - */ - public static ProxyInfo buildDirectProxy(String host, int port, List<String> exclList) { - String[] array = exclList.toArray(new String[exclList.size()]); - return new ProxyInfo(host, port, TextUtils.join(",", array), array); - } - - /** - * Construct a {@link ProxyInfo} that will download and run the PAC script - * at the specified URL. - */ - public static ProxyInfo buildPacProxy(Uri pacUri) { - return new ProxyInfo(pacUri); - } - - /** - * Construct a {@link ProxyInfo} object that will download and run the PAC script at the - * specified URL and port. - */ - @NonNull - public static ProxyInfo buildPacProxy(@NonNull Uri pacUrl, int port) { - return new ProxyInfo(pacUrl, port); - } - - /** - * Create a ProxyProperties that points at a HTTP Proxy. - * @hide - */ - @UnsupportedAppUsage - public ProxyInfo(String host, int port, String exclList) { - mHost = host; - mPort = port; - mExclusionList = exclList; - mParsedExclusionList = parseExclusionList(mExclusionList); - mPacFileUrl = Uri.EMPTY; - } - - /** - * Create a ProxyProperties that points at a PAC URL. - * @hide - */ - public ProxyInfo(@NonNull Uri pacFileUrl) { - mHost = LOCAL_HOST; - mPort = LOCAL_PORT; - mExclusionList = LOCAL_EXCL_LIST; - mParsedExclusionList = parseExclusionList(mExclusionList); - if (pacFileUrl == null) { - throw new NullPointerException(); - } - mPacFileUrl = pacFileUrl; - } - - /** - * Only used in PacProxyInstaller after Local Proxy is bound. - * @hide - */ - public ProxyInfo(@NonNull Uri pacFileUrl, int localProxyPort) { - mHost = LOCAL_HOST; - mPort = localProxyPort; - mExclusionList = LOCAL_EXCL_LIST; - mParsedExclusionList = parseExclusionList(mExclusionList); - if (pacFileUrl == null) { - throw new NullPointerException(); - } - mPacFileUrl = pacFileUrl; - } - - private static String[] parseExclusionList(String exclusionList) { - if (exclusionList == null) { - return new String[0]; - } else { - return exclusionList.toLowerCase(Locale.ROOT).split(","); - } - } - - private ProxyInfo(String host, int port, String exclList, String[] parsedExclList) { - mHost = host; - mPort = port; - mExclusionList = exclList; - mParsedExclusionList = parsedExclList; - mPacFileUrl = Uri.EMPTY; - } - - /** - * A copy constructor to hold proxy properties. - */ - public ProxyInfo(@Nullable ProxyInfo source) { - if (source != null) { - mHost = source.getHost(); - mPort = source.getPort(); - mPacFileUrl = source.mPacFileUrl; - mExclusionList = source.getExclusionListAsString(); - mParsedExclusionList = source.mParsedExclusionList; - } else { - mHost = null; - mPort = 0; - mExclusionList = null; - mParsedExclusionList = null; - mPacFileUrl = Uri.EMPTY; - } - } - - /** - * @hide - */ - public InetSocketAddress getSocketAddress() { - InetSocketAddress inetSocketAddress = null; - try { - inetSocketAddress = new InetSocketAddress(mHost, mPort); - } catch (IllegalArgumentException e) { } - return inetSocketAddress; - } - - /** - * Returns the URL of the current PAC script or null if there is - * no PAC script. - */ - public Uri getPacFileUrl() { - return mPacFileUrl; - } - - /** - * When configured to use a Direct Proxy this returns the host - * of the proxy. - */ - public String getHost() { - return mHost; - } - - /** - * When configured to use a Direct Proxy this returns the port - * of the proxy - */ - public int getPort() { - return mPort; - } - - /** - * When configured to use a Direct Proxy this returns the list - * of hosts for which the proxy is ignored. - */ - public String[] getExclusionList() { - return mParsedExclusionList; - } - - /** - * comma separated - * @hide - */ - @Nullable - public String getExclusionListAsString() { - return mExclusionList; - } - - /** - * Return true if the pattern of proxy is valid, otherwise return false. - */ - public boolean isValid() { - if (!Uri.EMPTY.equals(mPacFileUrl)) return true; - return Proxy.PROXY_VALID == Proxy.validate(mHost == null ? "" : mHost, - mPort == 0 ? "" : Integer.toString(mPort), - mExclusionList == null ? "" : mExclusionList); - } - - /** - * @hide - */ - public java.net.Proxy makeProxy() { - java.net.Proxy proxy = java.net.Proxy.NO_PROXY; - if (mHost != null) { - try { - InetSocketAddress inetSocketAddress = new InetSocketAddress(mHost, mPort); - proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, inetSocketAddress); - } catch (IllegalArgumentException e) { - } - } - return proxy; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - if (!Uri.EMPTY.equals(mPacFileUrl)) { - sb.append("PAC Script: "); - sb.append(mPacFileUrl); - } - if (mHost != null) { - sb.append("["); - sb.append(mHost); - sb.append("] "); - sb.append(Integer.toString(mPort)); - if (mExclusionList != null) { - sb.append(" xl=").append(mExclusionList); - } - } else { - sb.append("[ProxyProperties.mHost == null]"); - } - return sb.toString(); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof ProxyInfo)) return false; - ProxyInfo p = (ProxyInfo)o; - // If PAC URL is present in either then they must be equal. - // Other parameters will only be for fall back. - if (!Uri.EMPTY.equals(mPacFileUrl)) { - return mPacFileUrl.equals(p.getPacFileUrl()) && mPort == p.mPort; - } - if (!Uri.EMPTY.equals(p.mPacFileUrl)) { - return false; - } - if (mExclusionList != null && !mExclusionList.equals(p.getExclusionListAsString())) { - return false; - } - if (mHost != null && p.getHost() != null && mHost.equals(p.getHost()) == false) { - return false; - } - if (mHost != null && p.mHost == null) return false; - if (mHost == null && p.mHost != null) return false; - if (mPort != p.mPort) return false; - return true; - } - - /** - * Implement the Parcelable interface - * @hide - */ - public int describeContents() { - return 0; - } - - @Override - /* - * generate hashcode based on significant fields - */ - public int hashCode() { - return ((null == mHost) ? 0 : mHost.hashCode()) - + ((null == mExclusionList) ? 0 : mExclusionList.hashCode()) - + mPort; - } - - /** - * Implement the Parcelable interface. - * @hide - */ - public void writeToParcel(Parcel dest, int flags) { - if (!Uri.EMPTY.equals(mPacFileUrl)) { - dest.writeByte((byte)1); - mPacFileUrl.writeToParcel(dest, 0); - dest.writeInt(mPort); - return; - } else { - dest.writeByte((byte)0); - } - if (mHost != null) { - dest.writeByte((byte)1); - dest.writeString(mHost); - dest.writeInt(mPort); - } else { - dest.writeByte((byte)0); - } - dest.writeString(mExclusionList); - dest.writeStringArray(mParsedExclusionList); - } - - public static final @android.annotation.NonNull Creator<ProxyInfo> CREATOR = - new Creator<ProxyInfo>() { - public ProxyInfo createFromParcel(Parcel in) { - String host = null; - int port = 0; - if (in.readByte() != 0) { - Uri url = Uri.CREATOR.createFromParcel(in); - int localPort = in.readInt(); - return new ProxyInfo(url, localPort); - } - if (in.readByte() != 0) { - host = in.readString(); - port = in.readInt(); - } - String exclList = in.readString(); - String[] parsedExclList = in.createStringArray(); - ProxyInfo proxyProperties = new ProxyInfo(host, port, exclList, parsedExclList); - return proxyProperties; - } - - public ProxyInfo[] newArray(int size) { - return new ProxyInfo[size]; - } - }; -} diff --git a/core/java/android/net/RouteInfo.aidl b/core/java/android/net/RouteInfo.aidl deleted file mode 100644 index 7af9fdaef342..000000000000 --- a/core/java/android/net/RouteInfo.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -@JavaOnlyStableParcelable parcelable RouteInfo; diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java deleted file mode 100644 index 94f849f006f3..000000000000 --- a/core/java/android/net/RouteInfo.java +++ /dev/null @@ -1,658 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; - -import com.android.net.module.util.NetUtils; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Collection; -import java.util.Objects; - -/** - * Represents a network route. - * <p> - * This is used both to describe static network configuration and live network - * configuration information. - * - * A route contains three pieces of information: - * <ul> - * <li>a destination {@link IpPrefix} specifying the network destinations covered by this route. - * If this is {@code null} it indicates a default route of the address family (IPv4 or IPv6) - * implied by the gateway IP address. - * <li>a gateway {@link InetAddress} indicating the next hop to use. If this is {@code null} it - * indicates a directly-connected route. - * <li>an interface (which may be unspecified). - * </ul> - * Either the destination or the gateway may be {@code null}, but not both. If the - * destination and gateway are both specified, they must be of the same address family - * (IPv4 or IPv6). - */ -public final class RouteInfo implements Parcelable { - /** @hide */ - @IntDef(value = { - RTN_UNICAST, - RTN_UNREACHABLE, - RTN_THROW, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface RouteType {} - - /** - * The IP destination address for this route. - */ - @NonNull - private final IpPrefix mDestination; - - /** - * The gateway address for this route. - */ - @UnsupportedAppUsage - @Nullable - private final InetAddress mGateway; - - /** - * The interface for this route. - */ - @Nullable - private final String mInterface; - - - /** Unicast route. @hide */ - @SystemApi - public static final int RTN_UNICAST = 1; - - /** Unreachable route. @hide */ - @SystemApi - public static final int RTN_UNREACHABLE = 7; - - /** Throw route. @hide */ - @SystemApi - public static final int RTN_THROW = 9; - - /** - * The type of this route; one of the RTN_xxx constants above. - */ - private final int mType; - - /** - * The maximum transmission unit size for this route. - */ - private final int mMtu; - - // Derived data members. - // TODO: remove these. - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - private final boolean mIsHost; - private final boolean mHasGateway; - - /** - * Constructs a RouteInfo object. - * - * If destination is null, then gateway must be specified and the - * constructed route is either the IPv4 default route <code>0.0.0.0</code> - * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default - * route <code>::/0</code> if gateway is an instance of - * {@link Inet6Address}. - * <p> - * destination and gateway may not both be null. - * - * @param destination the destination prefix - * @param gateway the IP address to route packets through - * @param iface the interface name to send packets on - * @param type the type of this route - * - * @hide - */ - @SystemApi - public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway, - @Nullable String iface, @RouteType int type) { - this(destination, gateway, iface, type, 0); - } - - /** - * Constructs a RouteInfo object. - * - * If destination is null, then gateway must be specified and the - * constructed route is either the IPv4 default route <code>0.0.0.0</code> - * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default - * route <code>::/0</code> if gateway is an instance of - * {@link Inet6Address}. - * <p> - * destination and gateway may not both be null. - * - * @param destination the destination prefix - * @param gateway the IP address to route packets through - * @param iface the interface name to send packets on - * @param type the type of this route - * @param mtu the maximum transmission unit size for this route - * - * @hide - */ - @SystemApi - public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway, - @Nullable String iface, @RouteType int type, int mtu) { - switch (type) { - case RTN_UNICAST: - case RTN_UNREACHABLE: - case RTN_THROW: - // TODO: It would be nice to ensure that route types that don't have nexthops or - // interfaces, such as unreachable or throw, can't be created if an interface or - // a gateway is specified. This is a bit too complicated to do at the moment - // because: - // - // - LinkProperties sets the interface on routes added to it, and modifies the - // interfaces of all the routes when its interface name changes. - // - Even when the gateway is null, we store a non-null gateway here. - // - // For now, we just rely on the code that sets routes to do things properly. - break; - default: - throw new IllegalArgumentException("Unknown route type " + type); - } - - if (destination == null) { - if (gateway != null) { - if (gateway instanceof Inet4Address) { - destination = new IpPrefix(Inet4Address.ANY, 0); - } else { - destination = new IpPrefix(Inet6Address.ANY, 0); - } - } else { - // no destination, no gateway. invalid. - throw new IllegalArgumentException("Invalid arguments passed in: " + gateway + "," + - destination); - } - } - // TODO: set mGateway to null if there is no gateway. This is more correct, saves space, and - // matches the documented behaviour. Before we can do this we need to fix all callers (e.g., - // ConnectivityService) to stop doing things like r.getGateway().equals(), ... . - if (gateway == null) { - if (destination.getAddress() instanceof Inet4Address) { - gateway = Inet4Address.ANY; - } else { - gateway = Inet6Address.ANY; - } - } - mHasGateway = (!gateway.isAnyLocalAddress()); - - if ((destination.getAddress() instanceof Inet4Address - && !(gateway instanceof Inet4Address)) - || (destination.getAddress() instanceof Inet6Address - && !(gateway instanceof Inet6Address))) { - throw new IllegalArgumentException("address family mismatch in RouteInfo constructor"); - } - mDestination = destination; // IpPrefix objects are immutable. - mGateway = gateway; // InetAddress objects are immutable. - mInterface = iface; // Strings are immutable. - mType = type; - mIsHost = isHost(); - mMtu = mtu; - } - - /** - * Constructs a {@code RouteInfo} object. - * - * If destination is null, then gateway must be specified and the - * constructed route is either the IPv4 default route <code>0.0.0.0</code> - * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default - * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}. - * <p> - * Destination and gateway may not both be null. - * - * @param destination the destination address and prefix in an {@link IpPrefix} - * @param gateway the {@link InetAddress} to route packets through - * @param iface the interface name to send packets on - * - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway, - @Nullable String iface) { - this(destination, gateway, iface, RTN_UNICAST); - } - - /** - * @hide - */ - @UnsupportedAppUsage - public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway, - @Nullable String iface) { - this(destination == null ? null : - new IpPrefix(destination.getAddress(), destination.getPrefixLength()), - gateway, iface); - } - - /** - * Constructs a {@code RouteInfo} object. - * - * If destination is null, then gateway must be specified and the - * constructed route is either the IPv4 default route <code>0.0.0.0</code> - * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default - * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}. - * <p> - * Destination and gateway may not both be null. - * - * @param destination the destination address and prefix in an {@link IpPrefix} - * @param gateway the {@link InetAddress} to route packets through - * - * @hide - */ - public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway) { - this(destination, gateway, null); - } - - /** - * @hide - * - * TODO: Remove this. - */ - @UnsupportedAppUsage - public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway) { - this(destination, gateway, null); - } - - /** - * Constructs a default {@code RouteInfo} object. - * - * @param gateway the {@link InetAddress} to route packets through - * - * @hide - */ - @UnsupportedAppUsage - public RouteInfo(@NonNull InetAddress gateway) { - this((IpPrefix) null, gateway, null); - } - - /** - * Constructs a {@code RouteInfo} object representing a direct connected subnet. - * - * @param destination the {@link IpPrefix} describing the address and prefix - * length of the subnet. - * - * @hide - */ - public RouteInfo(@NonNull IpPrefix destination) { - this(destination, null, null); - } - - /** - * @hide - */ - public RouteInfo(@NonNull LinkAddress destination) { - this(destination, null, null); - } - - /** - * @hide - */ - public RouteInfo(@NonNull IpPrefix destination, @RouteType int type) { - this(destination, null, null, type); - } - - /** - * @hide - */ - public static RouteInfo makeHostRoute(@NonNull InetAddress host, @Nullable String iface) { - return makeHostRoute(host, null, iface); - } - - /** - * @hide - */ - public static RouteInfo makeHostRoute(@Nullable InetAddress host, @Nullable InetAddress gateway, - @Nullable String iface) { - if (host == null) return null; - - if (host instanceof Inet4Address) { - return new RouteInfo(new IpPrefix(host, 32), gateway, iface); - } else { - return new RouteInfo(new IpPrefix(host, 128), gateway, iface); - } - } - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - private boolean isHost() { - return (mDestination.getAddress() instanceof Inet4Address && - mDestination.getPrefixLength() == 32) || - (mDestination.getAddress() instanceof Inet6Address && - mDestination.getPrefixLength() == 128); - } - - /** - * Retrieves the destination address and prefix length in the form of an {@link IpPrefix}. - * - * @return {@link IpPrefix} specifying the destination. This is never {@code null}. - */ - @NonNull - public IpPrefix getDestination() { - return mDestination; - } - - /** - * TODO: Convert callers to use IpPrefix and then remove. - * @hide - */ - @NonNull - public LinkAddress getDestinationLinkAddress() { - return new LinkAddress(mDestination.getAddress(), mDestination.getPrefixLength()); - } - - /** - * Retrieves the gateway or next hop {@link InetAddress} for this route. - * - * @return {@link InetAddress} specifying the gateway or next hop. This may be - * {@code null} for a directly-connected route." - */ - @Nullable - public InetAddress getGateway() { - return mGateway; - } - - /** - * Retrieves the interface used for this route if specified, else {@code null}. - * - * @return The name of the interface used for this route. - */ - @Nullable - public String getInterface() { - return mInterface; - } - - /** - * Retrieves the type of this route. - * - * @return The type of this route; one of the {@code RTN_xxx} constants defined in this class. - * - * @hide - */ - @SystemApi - @RouteType - public int getType() { - return mType; - } - - /** - * Retrieves the MTU size for this route. - * - * @return The MTU size, or 0 if it has not been set. - * @hide - */ - @SystemApi - public int getMtu() { - return mMtu; - } - - /** - * Indicates if this route is a default route (ie, has no destination specified). - * - * @return {@code true} if the destination has a prefix length of 0. - */ - public boolean isDefaultRoute() { - return mType == RTN_UNICAST && mDestination.getPrefixLength() == 0; - } - - /** - * Indicates if this route is an unreachable default route. - * - * @return {@code true} if it's an unreachable route with prefix length of 0. - * @hide - */ - private boolean isUnreachableDefaultRoute() { - return mType == RTN_UNREACHABLE && mDestination.getPrefixLength() == 0; - } - - /** - * Indicates if this route is an IPv4 default route. - * @hide - */ - public boolean isIPv4Default() { - return isDefaultRoute() && mDestination.getAddress() instanceof Inet4Address; - } - - /** - * Indicates if this route is an IPv4 unreachable default route. - * @hide - */ - public boolean isIPv4UnreachableDefault() { - return isUnreachableDefaultRoute() && mDestination.getAddress() instanceof Inet4Address; - } - - /** - * Indicates if this route is an IPv6 default route. - * @hide - */ - public boolean isIPv6Default() { - return isDefaultRoute() && mDestination.getAddress() instanceof Inet6Address; - } - - /** - * Indicates if this route is an IPv6 unreachable default route. - * @hide - */ - public boolean isIPv6UnreachableDefault() { - return isUnreachableDefaultRoute() && mDestination.getAddress() instanceof Inet6Address; - } - - /** - * Indicates if this route is a host route (ie, matches only a single host address). - * - * @return {@code true} if the destination has a prefix length of 32 or 128 for IPv4 or IPv6, - * respectively. - * @hide - */ - public boolean isHostRoute() { - return mIsHost; - } - - /** - * Indicates if this route has a next hop ({@code true}) or is directly-connected - * ({@code false}). - * - * @return {@code true} if a gateway is specified - */ - public boolean hasGateway() { - return mHasGateway; - } - - /** - * Determines whether the destination and prefix of this route includes the specified - * address. - * - * @param destination A {@link InetAddress} to test to see if it would match this route. - * @return {@code true} if the destination and prefix length cover the given address. - */ - public boolean matches(InetAddress destination) { - return mDestination.contains(destination); - } - - /** - * Find the route from a Collection of routes that best matches a given address. - * May return null if no routes are applicable. - * @param routes a Collection of RouteInfos to chose from - * @param dest the InetAddress your trying to get to - * @return the RouteInfo from the Collection that best fits the given address - * - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @Nullable - public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) { - return NetUtils.selectBestRoute(routes, dest); - } - - /** - * Returns a human-readable description of this object. - */ - public String toString() { - String val = ""; - if (mDestination != null) val = mDestination.toString(); - if (mType == RTN_UNREACHABLE) { - val += " unreachable"; - } else if (mType == RTN_THROW) { - val += " throw"; - } else { - val += " ->"; - if (mGateway != null) val += " " + mGateway.getHostAddress(); - if (mInterface != null) val += " " + mInterface; - if (mType != RTN_UNICAST) { - val += " unknown type " + mType; - } - } - val += " mtu " + mMtu; - return val; - } - - /** - * Compares this RouteInfo object against the specified object and indicates if they are equal. - * @return {@code true} if the objects are equal, {@code false} otherwise. - */ - public boolean equals(Object obj) { - if (this == obj) return true; - - if (!(obj instanceof RouteInfo)) return false; - - RouteInfo target = (RouteInfo) obj; - - return Objects.equals(mDestination, target.getDestination()) && - Objects.equals(mGateway, target.getGateway()) && - Objects.equals(mInterface, target.getInterface()) && - mType == target.getType() && mMtu == target.getMtu(); - } - - /** - * A helper class that contains the destination, the gateway and the interface in a - * {@code RouteInfo}, used by {@link ConnectivityService#updateRoutes} or - * {@link LinkProperties#addRoute} to calculate the list to be updated. - * {@code RouteInfo} objects with different interfaces are treated as different routes because - * *usually* on Android different interfaces use different routing tables, and moving a route - * to a new routing table never constitutes an update, but is always a remove and an add. - * - * @hide - */ - public static class RouteKey { - @NonNull private final IpPrefix mDestination; - @Nullable private final InetAddress mGateway; - @Nullable private final String mInterface; - - RouteKey(@NonNull IpPrefix destination, @Nullable InetAddress gateway, - @Nullable String iface) { - mDestination = destination; - mGateway = gateway; - mInterface = iface; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof RouteKey)) { - return false; - } - RouteKey p = (RouteKey) o; - // No need to do anything special for scoped addresses. Inet6Address#equals does not - // consider the scope ID, but the netd route IPCs (e.g., INetd#networkAddRouteParcel) - // and the kernel ignore scoped addresses both in the prefix and in the nexthop and only - // look at RTA_OIF. - return Objects.equals(p.mDestination, mDestination) - && Objects.equals(p.mGateway, mGateway) - && Objects.equals(p.mInterface, mInterface); - } - - @Override - public int hashCode() { - return Objects.hash(mDestination, mGateway, mInterface); - } - } - - /** - * Get {@code RouteKey} of this {@code RouteInfo}. - * @return a {@code RouteKey} object. - * - * @hide - */ - @NonNull - public RouteKey getRouteKey() { - return new RouteKey(mDestination, mGateway, mInterface); - } - - /** - * Returns a hashcode for this <code>RouteInfo</code> object. - */ - public int hashCode() { - return (mDestination.hashCode() * 41) - + (mGateway == null ? 0 :mGateway.hashCode() * 47) - + (mInterface == null ? 0 :mInterface.hashCode() * 67) - + (mType * 71) + (mMtu * 89); - } - - /** - * Implement the Parcelable interface - */ - public int describeContents() { - return 0; - } - - /** - * Implement the Parcelable interface - */ - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(mDestination, flags); - byte[] gatewayBytes = (mGateway == null) ? null : mGateway.getAddress(); - dest.writeByteArray(gatewayBytes); - dest.writeString(mInterface); - dest.writeInt(mType); - dest.writeInt(mMtu); - } - - /** - * Implement the Parcelable interface. - */ - public static final @android.annotation.NonNull Creator<RouteInfo> CREATOR = - new Creator<RouteInfo>() { - public RouteInfo createFromParcel(Parcel in) { - IpPrefix dest = in.readParcelable(null); - - InetAddress gateway = null; - byte[] addr = in.createByteArray(); - try { - gateway = InetAddress.getByAddress(addr); - } catch (UnknownHostException e) {} - - String iface = in.readString(); - int type = in.readInt(); - int mtu = in.readInt(); - - return new RouteInfo(dest, gateway, iface, type, mtu); - } - - public RouteInfo[] newArray(int size) { - return new RouteInfo[size]; - } - }; -} diff --git a/core/java/android/net/SocketKeepalive.java b/core/java/android/net/SocketKeepalive.java deleted file mode 100644 index d007a9520cb5..000000000000 --- a/core/java/android/net/SocketKeepalive.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.IntDef; -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.os.Binder; -import android.os.ParcelFileDescriptor; -import android.os.RemoteException; - -import java.io.IOException; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.concurrent.Executor; - -/** - * Allows applications to request that the system periodically send specific packets on their - * behalf, using hardware offload to save battery power. - * - * To request that the system send keepalives, call one of the methods that return a - * {@link SocketKeepalive} object, such as {@link ConnectivityManager#createSocketKeepalive}, - * passing in a non-null callback. If the {@link SocketKeepalive} is successfully - * started, the callback's {@code onStarted} method will be called. If an error occurs, - * {@code onError} will be called, specifying one of the {@code ERROR_*} constants in this - * class. - * - * To stop an existing keepalive, call {@link SocketKeepalive#stop}. The system will call - * {@link SocketKeepalive.Callback#onStopped} if the operation was successful or - * {@link SocketKeepalive.Callback#onError} if an error occurred. - * - * For cellular, the device MUST support at least 1 keepalive slot. - * - * For WiFi, the device SHOULD support keepalive offload. If it does not, it MUST reply with - * {@link SocketKeepalive.Callback#onError} with {@code ERROR_UNSUPPORTED} to any keepalive offload - * request. If it does, it MUST support at least 3 concurrent keepalive slots. - */ -public abstract class SocketKeepalive implements AutoCloseable { - static final String TAG = "SocketKeepalive"; - - /** - * No errors. - * @hide - */ - @SystemApi - public static final int SUCCESS = 0; - - /** @hide */ - public static final int NO_KEEPALIVE = -1; - - /** @hide */ - public static final int DATA_RECEIVED = -2; - - /** @hide */ - public static final int BINDER_DIED = -10; - - /** The specified {@code Network} is not connected. */ - public static final int ERROR_INVALID_NETWORK = -20; - /** The specified IP addresses are invalid. For example, the specified source IP address is - * not configured on the specified {@code Network}. */ - public static final int ERROR_INVALID_IP_ADDRESS = -21; - /** The requested port is invalid. */ - public static final int ERROR_INVALID_PORT = -22; - /** The packet length is invalid (e.g., too long). */ - public static final int ERROR_INVALID_LENGTH = -23; - /** The packet transmission interval is invalid (e.g., too short). */ - public static final int ERROR_INVALID_INTERVAL = -24; - /** The target socket is invalid. */ - public static final int ERROR_INVALID_SOCKET = -25; - /** The target socket is not idle. */ - public static final int ERROR_SOCKET_NOT_IDLE = -26; - /** - * The stop reason is uninitialized. This should only be internally used as initial state - * of stop reason, instead of propagating to application. - * @hide - */ - public static final int ERROR_STOP_REASON_UNINITIALIZED = -27; - - /** The device does not support this request. */ - public static final int ERROR_UNSUPPORTED = -30; - /** @hide TODO: delete when telephony code has been updated. */ - public static final int ERROR_HARDWARE_UNSUPPORTED = ERROR_UNSUPPORTED; - /** The hardware returned an error. */ - public static final int ERROR_HARDWARE_ERROR = -31; - /** The limitation of resource is reached. */ - public static final int ERROR_INSUFFICIENT_RESOURCES = -32; - - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "ERROR_" }, value = { - ERROR_INVALID_NETWORK, - ERROR_INVALID_IP_ADDRESS, - ERROR_INVALID_PORT, - ERROR_INVALID_LENGTH, - ERROR_INVALID_INTERVAL, - ERROR_INVALID_SOCKET, - ERROR_SOCKET_NOT_IDLE - }) - public @interface ErrorCode {} - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(value = { - SUCCESS, - ERROR_INVALID_LENGTH, - ERROR_UNSUPPORTED, - ERROR_INSUFFICIENT_RESOURCES, - ERROR_HARDWARE_UNSUPPORTED - }) - public @interface KeepaliveEvent {} - - /** - * The minimum interval in seconds between keepalive packet transmissions. - * - * @hide - **/ - public static final int MIN_INTERVAL_SEC = 10; - - /** - * The maximum interval in seconds between keepalive packet transmissions. - * - * @hide - **/ - public static final int MAX_INTERVAL_SEC = 3600; - - /** - * An exception that embarks an error code. - * @hide - */ - public static class ErrorCodeException extends Exception { - public final int error; - public ErrorCodeException(final int error, final Throwable e) { - super(e); - this.error = error; - } - public ErrorCodeException(final int error) { - this.error = error; - } - } - - /** - * This socket is invalid. - * See the error code for details, and the optional cause. - * @hide - */ - public static class InvalidSocketException extends ErrorCodeException { - public InvalidSocketException(final int error, final Throwable e) { - super(error, e); - } - public InvalidSocketException(final int error) { - super(error); - } - } - - @NonNull final IConnectivityManager mService; - @NonNull final Network mNetwork; - @NonNull final ParcelFileDescriptor mPfd; - @NonNull final Executor mExecutor; - @NonNull final ISocketKeepaliveCallback mCallback; - // TODO: remove slot since mCallback could be used to identify which keepalive to stop. - @Nullable Integer mSlot; - - SocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network, - @NonNull ParcelFileDescriptor pfd, - @NonNull Executor executor, @NonNull Callback callback) { - mService = service; - mNetwork = network; - mPfd = pfd; - mExecutor = executor; - mCallback = new ISocketKeepaliveCallback.Stub() { - @Override - public void onStarted(int slot) { - final long token = Binder.clearCallingIdentity(); - try { - mExecutor.execute(() -> { - mSlot = slot; - callback.onStarted(); - }); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void onStopped() { - final long token = Binder.clearCallingIdentity(); - try { - executor.execute(() -> { - mSlot = null; - callback.onStopped(); - }); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void onError(int error) { - final long token = Binder.clearCallingIdentity(); - try { - executor.execute(() -> { - mSlot = null; - callback.onError(error); - }); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void onDataReceived() { - final long token = Binder.clearCallingIdentity(); - try { - executor.execute(() -> { - mSlot = null; - callback.onDataReceived(); - }); - } finally { - Binder.restoreCallingIdentity(token); - } - } - }; - } - - /** - * Request that keepalive be started with the given {@code intervalSec}. See - * {@link SocketKeepalive}. If the remote binder dies, or the binder call throws an exception - * when invoking start or stop of the {@link SocketKeepalive}, a {@link RemoteException} will be - * thrown into the {@code executor}. This is typically not important to catch because the remote - * party is the system, so if it is not in shape to communicate through binder the system is - * probably going down anyway. If the caller cares regardless, it can use a custom - * {@link Executor} to catch the {@link RemoteException}. - * - * @param intervalSec The target interval in seconds between keepalive packet transmissions. - * The interval should be between 10 seconds and 3600 seconds, otherwise - * {@link #ERROR_INVALID_INTERVAL} will be returned. - */ - public final void start(@IntRange(from = MIN_INTERVAL_SEC, to = MAX_INTERVAL_SEC) - int intervalSec) { - startImpl(intervalSec); - } - - abstract void startImpl(int intervalSec); - - /** - * Requests that keepalive be stopped. The application must wait for {@link Callback#onStopped} - * before using the object. See {@link SocketKeepalive}. - */ - public final void stop() { - stopImpl(); - } - - abstract void stopImpl(); - - /** - * Deactivate this {@link SocketKeepalive} and free allocated resources. The instance won't be - * usable again if {@code close()} is called. - */ - @Override - public final void close() { - stop(); - try { - mPfd.close(); - } catch (IOException e) { - // Nothing much can be done. - } - } - - /** - * The callback which app can use to learn the status changes of {@link SocketKeepalive}. See - * {@link SocketKeepalive}. - */ - public static class Callback { - /** The requested keepalive was successfully started. */ - public void onStarted() {} - /** The keepalive was successfully stopped. */ - public void onStopped() {} - /** An error occurred. */ - public void onError(@ErrorCode int error) {} - /** The keepalive on a TCP socket was stopped because the socket received data. This is - * never called for UDP sockets. */ - public void onDataReceived() {} - } -} diff --git a/core/java/android/net/StaticIpConfiguration.aidl b/core/java/android/net/StaticIpConfiguration.aidl deleted file mode 100644 index 8aac701fe7e1..000000000000 --- a/core/java/android/net/StaticIpConfiguration.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* -** -** Copyright (C) 2019 The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -package android.net; - -@JavaOnlyStableParcelable parcelable StaticIpConfiguration;
\ No newline at end of file diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java deleted file mode 100644 index ce545974f5cb..000000000000 --- a/core/java/android/net/StaticIpConfiguration.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; - -import com.android.internal.util.Preconditions; -import com.android.net.module.util.InetAddressUtils; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * Class that describes static IP configuration. - * - * <p>This class is different from {@link LinkProperties} because it represents - * configuration intent. The general contract is that if we can represent - * a configuration here, then we should be able to configure it on a network. - * The intent is that it closely match the UI we have for configuring networks. - * - * <p>In contrast, {@link LinkProperties} represents current state. It is much more - * expressive. For example, it supports multiple IP addresses, multiple routes, - * stacked interfaces, and so on. Because LinkProperties is so expressive, - * using it to represent configuration intent as well as current state causes - * problems. For example, we could unknowingly save a configuration that we are - * not in fact capable of applying, or we could save a configuration that the - * UI cannot display, which has the potential for malicious code to hide - * hostile or unexpected configuration from the user. - * - * @hide - */ -@SystemApi -public final class StaticIpConfiguration implements Parcelable { - /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @Nullable - public LinkAddress ipAddress; - /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @Nullable - public InetAddress gateway; - /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @NonNull - public final ArrayList<InetAddress> dnsServers; - /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @Nullable - public String domains; - - public StaticIpConfiguration() { - dnsServers = new ArrayList<>(); - } - - public StaticIpConfiguration(@Nullable StaticIpConfiguration source) { - this(); - if (source != null) { - // All of these except dnsServers are immutable, so no need to make copies. - ipAddress = source.ipAddress; - gateway = source.gateway; - dnsServers.addAll(source.dnsServers); - domains = source.domains; - } - } - - public void clear() { - ipAddress = null; - gateway = null; - dnsServers.clear(); - domains = null; - } - - /** - * Get the static IP address included in the configuration. - */ - public @Nullable LinkAddress getIpAddress() { - return ipAddress; - } - - /** - * Get the gateway included in the configuration. - */ - public @Nullable InetAddress getGateway() { - return gateway; - } - - /** - * Get the DNS servers included in the configuration. - */ - public @NonNull List<InetAddress> getDnsServers() { - return dnsServers; - } - - /** - * Get a {@link String} containing the comma separated domains to search when resolving host - * names on this link, in priority order. - */ - public @Nullable String getDomains() { - return domains; - } - - /** - * Helper class to build a new instance of {@link StaticIpConfiguration}. - */ - public static final class Builder { - private LinkAddress mIpAddress; - private InetAddress mGateway; - private Iterable<InetAddress> mDnsServers; - private String mDomains; - - /** - * Set the IP address to be included in the configuration; null by default. - * @return The {@link Builder} for chaining. - */ - public @NonNull Builder setIpAddress(@Nullable LinkAddress ipAddress) { - mIpAddress = ipAddress; - return this; - } - - /** - * Set the address of the gateway to be included in the configuration; null by default. - * @return The {@link Builder} for chaining. - */ - public @NonNull Builder setGateway(@Nullable InetAddress gateway) { - mGateway = gateway; - return this; - } - - /** - * Set the addresses of the DNS servers included in the configuration; empty by default. - * @return The {@link Builder} for chaining. - */ - public @NonNull Builder setDnsServers(@NonNull Iterable<InetAddress> dnsServers) { - Preconditions.checkNotNull(dnsServers); - mDnsServers = dnsServers; - return this; - } - - /** - * Sets the DNS domain search path to be used on the link; null by default. - * @param newDomains A {@link String} containing the comma separated domains to search when - * resolving host names on this link, in priority order. - * @return The {@link Builder} for chaining. - */ - public @NonNull Builder setDomains(@Nullable String newDomains) { - mDomains = newDomains; - return this; - } - - /** - * Create a {@link StaticIpConfiguration} from the parameters in this {@link Builder}. - * @return The newly created StaticIpConfiguration. - */ - public @NonNull StaticIpConfiguration build() { - final StaticIpConfiguration config = new StaticIpConfiguration(); - config.ipAddress = mIpAddress; - config.gateway = mGateway; - if (mDnsServers != null) { - for (InetAddress server : mDnsServers) { - config.dnsServers.add(server); - } - } - config.domains = mDomains; - return config; - } - } - - /** - * Add a DNS server to this configuration. - */ - public void addDnsServer(@NonNull InetAddress server) { - dnsServers.add(server); - } - - /** - * Returns the network routes specified by this object. Will typically include a - * directly-connected route for the IP address's local subnet and a default route. - * @param iface Interface to include in the routes. - */ - public @NonNull List<RouteInfo> getRoutes(@Nullable String iface) { - List<RouteInfo> routes = new ArrayList<RouteInfo>(3); - if (ipAddress != null) { - RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface); - routes.add(connectedRoute); - // If the default gateway is not covered by the directly-connected route, also add a - // host route to the gateway as well. This configuration is arguably invalid, but it - // used to work in K and earlier, and other OSes appear to accept it. - if (gateway != null && !connectedRoute.matches(gateway)) { - routes.add(RouteInfo.makeHostRoute(gateway, iface)); - } - } - if (gateway != null) { - routes.add(new RouteInfo((IpPrefix) null, gateway, iface)); - } - return routes; - } - - /** - * Returns a LinkProperties object expressing the data in this object. Note that the information - * contained in the LinkProperties will not be a complete picture of the link's configuration, - * because any configuration information that is obtained dynamically by the network (e.g., - * IPv6 configuration) will not be included. - * @hide - */ - public @NonNull LinkProperties toLinkProperties(String iface) { - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName(iface); - if (ipAddress != null) { - lp.addLinkAddress(ipAddress); - } - for (RouteInfo route : getRoutes(iface)) { - lp.addRoute(route); - } - for (InetAddress dns : dnsServers) { - lp.addDnsServer(dns); - } - lp.setDomains(domains); - return lp; - } - - @NonNull - @Override - public String toString() { - StringBuffer str = new StringBuffer(); - - str.append("IP address "); - if (ipAddress != null ) str.append(ipAddress).append(" "); - - str.append("Gateway "); - if (gateway != null) str.append(gateway.getHostAddress()).append(" "); - - str.append(" DNS servers: ["); - for (InetAddress dnsServer : dnsServers) { - str.append(" ").append(dnsServer.getHostAddress()); - } - - str.append(" ] Domains "); - if (domains != null) str.append(domains); - return str.toString(); - } - - @Override - public int hashCode() { - int result = 13; - result = 47 * result + (ipAddress == null ? 0 : ipAddress.hashCode()); - result = 47 * result + (gateway == null ? 0 : gateway.hashCode()); - result = 47 * result + (domains == null ? 0 : domains.hashCode()); - result = 47 * result + dnsServers.hashCode(); - return result; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) return true; - - if (!(obj instanceof StaticIpConfiguration)) return false; - - StaticIpConfiguration other = (StaticIpConfiguration) obj; - - return other != null && - Objects.equals(ipAddress, other.ipAddress) && - Objects.equals(gateway, other.gateway) && - dnsServers.equals(other.dnsServers) && - Objects.equals(domains, other.domains); - } - - /** Implement the Parcelable interface */ - public static final @android.annotation.NonNull Creator<StaticIpConfiguration> CREATOR = - new Creator<StaticIpConfiguration>() { - public StaticIpConfiguration createFromParcel(Parcel in) { - return readFromParcel(in); - } - - public StaticIpConfiguration[] newArray(int size) { - return new StaticIpConfiguration[size]; - } - }; - - /** Implement the Parcelable interface */ - @Override - public int describeContents() { - return 0; - } - - /** Implement the Parcelable interface */ - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(ipAddress, flags); - InetAddressUtils.parcelInetAddress(dest, gateway, flags); - dest.writeInt(dnsServers.size()); - for (InetAddress dnsServer : dnsServers) { - InetAddressUtils.parcelInetAddress(dest, dnsServer, flags); - } - dest.writeString(domains); - } - - /** @hide */ - public static StaticIpConfiguration readFromParcel(Parcel in) { - final StaticIpConfiguration s = new StaticIpConfiguration(); - s.ipAddress = in.readParcelable(null); - s.gateway = InetAddressUtils.unparcelInetAddress(in); - s.dnsServers.clear(); - int size = in.readInt(); - for (int i = 0; i < size; i++) { - s.dnsServers.add(InetAddressUtils.unparcelInetAddress(in)); - } - s.domains = in.readString(); - return s; - } -} diff --git a/core/java/android/net/TcpKeepalivePacketData.java b/core/java/android/net/TcpKeepalivePacketData.java deleted file mode 100644 index ddb3a6a72fb4..000000000000 --- a/core/java/android/net/TcpKeepalivePacketData.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.net.InetAddress; -import java.util.Objects; - -/** - * Represents the actual tcp keep alive packets which will be used for hardware offload. - * @hide - */ -@SystemApi -public final class TcpKeepalivePacketData extends KeepalivePacketData implements Parcelable { - private static final String TAG = "TcpKeepalivePacketData"; - - /** TCP sequence number. */ - public final int tcpSeq; - - /** TCP ACK number. */ - public final int tcpAck; - - /** TCP RCV window. */ - public final int tcpWindow; - - /** TCP RCV window scale. */ - public final int tcpWindowScale; - - /** IP TOS. */ - public final int ipTos; - - /** IP TTL. */ - public final int ipTtl; - - public TcpKeepalivePacketData(@NonNull final InetAddress srcAddress, int srcPort, - @NonNull final InetAddress dstAddress, int dstPort, @NonNull final byte[] data, - int tcpSeq, int tcpAck, int tcpWindow, int tcpWindowScale, int ipTos, int ipTtl) - throws InvalidPacketException { - super(srcAddress, srcPort, dstAddress, dstPort, data); - this.tcpSeq = tcpSeq; - this.tcpAck = tcpAck; - this.tcpWindow = tcpWindow; - this.tcpWindowScale = tcpWindowScale; - this.ipTos = ipTos; - this.ipTtl = ipTtl; - } - - @Override - public boolean equals(@Nullable final Object o) { - if (!(o instanceof TcpKeepalivePacketData)) return false; - final TcpKeepalivePacketData other = (TcpKeepalivePacketData) o; - final InetAddress srcAddress = getSrcAddress(); - final InetAddress dstAddress = getDstAddress(); - return srcAddress.equals(other.getSrcAddress()) - && dstAddress.equals(other.getDstAddress()) - && getSrcPort() == other.getSrcPort() - && getDstPort() == other.getDstPort() - && this.tcpAck == other.tcpAck - && this.tcpSeq == other.tcpSeq - && this.tcpWindow == other.tcpWindow - && this.tcpWindowScale == other.tcpWindowScale - && this.ipTos == other.ipTos - && this.ipTtl == other.ipTtl; - } - - @Override - public int hashCode() { - return Objects.hash(getSrcAddress(), getDstAddress(), getSrcPort(), getDstPort(), - tcpAck, tcpSeq, tcpWindow, tcpWindowScale, ipTos, ipTtl); - } - - /** - * Parcelable Implementation. - * Note that this object implements parcelable (and needs to keep doing this as it inherits - * from a class that does), but should usually be parceled as a stable parcelable using - * the toStableParcelable() and fromStableParcelable() methods. - */ - @Override - public int describeContents() { - return 0; - } - - /** Write to parcel. */ - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeString(getSrcAddress().getHostAddress()); - out.writeString(getDstAddress().getHostAddress()); - out.writeInt(getSrcPort()); - out.writeInt(getDstPort()); - out.writeByteArray(getPacket()); - out.writeInt(tcpSeq); - out.writeInt(tcpAck); - out.writeInt(tcpWindow); - out.writeInt(tcpWindowScale); - out.writeInt(ipTos); - out.writeInt(ipTtl); - } - - private static TcpKeepalivePacketData readFromParcel(Parcel in) throws InvalidPacketException { - InetAddress srcAddress = InetAddresses.parseNumericAddress(in.readString()); - InetAddress dstAddress = InetAddresses.parseNumericAddress(in.readString()); - int srcPort = in.readInt(); - int dstPort = in.readInt(); - byte[] packet = in.createByteArray(); - int tcpSeq = in.readInt(); - int tcpAck = in.readInt(); - int tcpWnd = in.readInt(); - int tcpWndScale = in.readInt(); - int ipTos = in.readInt(); - int ipTtl = in.readInt(); - return new TcpKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, packet, tcpSeq, - tcpAck, tcpWnd, tcpWndScale, ipTos, ipTtl); - } - - /** Parcelable Creator. */ - public static final @NonNull Parcelable.Creator<TcpKeepalivePacketData> CREATOR = - new Parcelable.Creator<TcpKeepalivePacketData>() { - public TcpKeepalivePacketData createFromParcel(Parcel in) { - try { - return readFromParcel(in); - } catch (InvalidPacketException e) { - throw new IllegalArgumentException( - "Invalid TCP keepalive data: " + e.getError()); - } - } - - public TcpKeepalivePacketData[] newArray(int size) { - return new TcpKeepalivePacketData[size]; - } - }; - - @Override - public String toString() { - return "saddr: " + getSrcAddress() - + " daddr: " + getDstAddress() - + " sport: " + getSrcPort() - + " dport: " + getDstPort() - + " seq: " + tcpSeq - + " ack: " + tcpAck - + " window: " + tcpWindow - + " windowScale: " + tcpWindowScale - + " tos: " + ipTos - + " ttl: " + ipTtl; - } -} diff --git a/core/java/android/net/TcpRepairWindow.java b/core/java/android/net/TcpRepairWindow.java deleted file mode 100644 index f062fa9034ea..000000000000 --- a/core/java/android/net/TcpRepairWindow.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.SystemApi; - -/** - * Corresponds to C's {@code struct tcp_repair_window} from - * include/uapi/linux/tcp.h - * - * @hide - */ -@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) -public final class TcpRepairWindow { - public final int sndWl1; - public final int sndWnd; - public final int maxWindow; - public final int rcvWnd; - public final int rcvWup; - public final int rcvWndScale; - - /** - * Constructs an instance with the given field values. - */ - public TcpRepairWindow(final int sndWl1, final int sndWnd, final int maxWindow, - final int rcvWnd, final int rcvWup, final int rcvWndScale) { - this.sndWl1 = sndWl1; - this.sndWnd = sndWnd; - this.maxWindow = maxWindow; - this.rcvWnd = rcvWnd; - this.rcvWup = rcvWup; - this.rcvWndScale = rcvWndScale; - } -} diff --git a/core/java/android/net/TcpSocketKeepalive.java b/core/java/android/net/TcpSocketKeepalive.java deleted file mode 100644 index d89814d49bd0..000000000000 --- a/core/java/android/net/TcpSocketKeepalive.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; -import android.os.ParcelFileDescriptor; -import android.os.RemoteException; -import android.util.Log; - -import java.util.concurrent.Executor; - -/** @hide */ -final class TcpSocketKeepalive extends SocketKeepalive { - - TcpSocketKeepalive(@NonNull IConnectivityManager service, - @NonNull Network network, - @NonNull ParcelFileDescriptor pfd, - @NonNull Executor executor, - @NonNull Callback callback) { - super(service, network, pfd, executor, callback); - } - - /** - * Starts keepalives. {@code mSocket} must be a connected TCP socket. - * - * - The application must not write to or read from the socket after calling this method, until - * onDataReceived, onStopped, or onError are called. If it does, the keepalive will fail - * with {@link #ERROR_SOCKET_NOT_IDLE}, or {@code #ERROR_INVALID_SOCKET} if the socket - * experienced an error (as in poll(2) returned POLLERR or POLLHUP); if this happens, the data - * received from the socket may be invalid, and the socket can't be recovered. - * - If the socket has data in the send or receive buffer, then this call will fail with - * {@link #ERROR_SOCKET_NOT_IDLE} and can be retried after the data has been processed. - * An app could ensure this by using an application-layer protocol to receive acknowledgement - * that indicates all data has been delivered to server, e.g. HTTP 200 OK. - * Then the app could go into keepalive mode after reading all remaining data within the - * acknowledgement. - */ - @Override - void startImpl(int intervalSec) { - mExecutor.execute(() -> { - try { - mService.startTcpKeepalive(mNetwork, mPfd, intervalSec, mCallback); - } catch (RemoteException e) { - Log.e(TAG, "Error starting packet keepalive: ", e); - throw e.rethrowFromSystemServer(); - } - }); - } - - @Override - void stopImpl() { - mExecutor.execute(() -> { - try { - if (mSlot != null) { - mService.stopKeepalive(mNetwork, mSlot); - } - } catch (RemoteException e) { - Log.e(TAG, "Error stopping packet keepalive: ", e); - throw e.rethrowFromSystemServer(); - } - }); - } -} diff --git a/core/java/android/net/TestNetworkInterface.aidl b/core/java/android/net/TestNetworkInterface.aidl deleted file mode 100644 index e1f4f9f794eb..000000000000 --- a/core/java/android/net/TestNetworkInterface.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -/** @hide */ -parcelable TestNetworkInterface; diff --git a/core/java/android/net/TestNetworkInterface.java b/core/java/android/net/TestNetworkInterface.java deleted file mode 100644 index 4449ff80180b..000000000000 --- a/core/java/android/net/TestNetworkInterface.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.ParcelFileDescriptor; -import android.os.Parcelable; - -/** - * This class is used to return the interface name and fd of the test interface - * - * @hide - */ -@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) -public final class TestNetworkInterface implements Parcelable { - @NonNull - private final ParcelFileDescriptor mFileDescriptor; - @NonNull - private final String mInterfaceName; - - @Override - public int describeContents() { - return (mFileDescriptor != null) ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0; - } - - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeParcelable(mFileDescriptor, PARCELABLE_WRITE_RETURN_VALUE); - out.writeString(mInterfaceName); - } - - public TestNetworkInterface(@NonNull ParcelFileDescriptor pfd, @NonNull String intf) { - mFileDescriptor = pfd; - mInterfaceName = intf; - } - - private TestNetworkInterface(@NonNull Parcel in) { - mFileDescriptor = in.readParcelable(ParcelFileDescriptor.class.getClassLoader()); - mInterfaceName = in.readString(); - } - - @NonNull - public ParcelFileDescriptor getFileDescriptor() { - return mFileDescriptor; - } - - @NonNull - public String getInterfaceName() { - return mInterfaceName; - } - - @NonNull - public static final Parcelable.Creator<TestNetworkInterface> CREATOR = - new Parcelable.Creator<TestNetworkInterface>() { - public TestNetworkInterface createFromParcel(Parcel in) { - return new TestNetworkInterface(in); - } - - public TestNetworkInterface[] newArray(int size) { - return new TestNetworkInterface[size]; - } - }; -} diff --git a/core/java/android/net/TestNetworkManager.java b/core/java/android/net/TestNetworkManager.java deleted file mode 100644 index 4e894143bf91..000000000000 --- a/core/java/android/net/TestNetworkManager.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.os.IBinder; -import android.os.RemoteException; - -import com.android.internal.util.Preconditions; - -import java.util.Arrays; -import java.util.Collection; - -/** - * Class that allows creation and management of per-app, test-only networks - * - * @hide - */ -@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) -public class TestNetworkManager { - /** - * Prefix for tun interfaces created by this class. - * @hide - */ - public static final String TEST_TUN_PREFIX = "testtun"; - - /** - * Prefix for tap interfaces created by this class. - * @hide - */ - public static final String TEST_TAP_PREFIX = "testtap"; - - @NonNull private static final String TAG = TestNetworkManager.class.getSimpleName(); - - @NonNull private final ITestNetworkManager mService; - - /** @hide */ - public TestNetworkManager(@NonNull ITestNetworkManager service) { - mService = Preconditions.checkNotNull(service, "missing ITestNetworkManager"); - } - - /** - * Teardown the capability-limited, testing-only network for a given interface - * - * @param network The test network that should be torn down - * @hide - */ - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public void teardownTestNetwork(@NonNull Network network) { - try { - mService.teardownTestNetwork(network.netId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - private void setupTestNetwork( - @NonNull String iface, - @Nullable LinkProperties lp, - boolean isMetered, - @NonNull int[] administratorUids, - @NonNull IBinder binder) { - try { - mService.setupTestNetwork(iface, lp, isMetered, administratorUids, binder); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Sets up a capability-limited, testing-only network for a given interface - * - * @param lp The LinkProperties for the TestNetworkService to use for this test network. Note - * that the interface name and link addresses will be overwritten, and the passed-in values - * discarded. - * @param isMetered Whether or not the network should be considered metered. - * @param binder A binder object guarding the lifecycle of this test network. - * @hide - */ - public void setupTestNetwork( - @NonNull LinkProperties lp, boolean isMetered, @NonNull IBinder binder) { - Preconditions.checkNotNull(lp, "Invalid LinkProperties"); - setupTestNetwork(lp.getInterfaceName(), lp, isMetered, new int[0], binder); - } - - /** - * Sets up a capability-limited, testing-only network for a given interface - * - * @param iface the name of the interface to be used for the Network LinkProperties. - * @param binder A binder object guarding the lifecycle of this test network. - * @hide - */ - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) { - setupTestNetwork(iface, null, true, new int[0], binder); - } - - /** - * Sets up a capability-limited, testing-only network for a given interface with the given - * administrator UIDs. - * - * @param iface the name of the interface to be used for the Network LinkProperties. - * @param administratorUids The administrator UIDs to be used for the test-only network - * @param binder A binder object guarding the lifecycle of this test network. - * @hide - */ - public void setupTestNetwork( - @NonNull String iface, @NonNull int[] administratorUids, @NonNull IBinder binder) { - setupTestNetwork(iface, null, true, administratorUids, binder); - } - - /** - * Create a tun interface for testing purposes - * - * @param linkAddrs an array of LinkAddresses to assign to the TUN interface - * @return A ParcelFileDescriptor of the underlying TUN interface. Close this to tear down the - * TUN interface. - * @deprecated Use {@link #createTunInterface(Collection)} instead. - * @hide - */ - @Deprecated - @NonNull - public TestNetworkInterface createTunInterface(@NonNull LinkAddress[] linkAddrs) { - return createTunInterface(Arrays.asList(linkAddrs)); - } - - /** - * Create a tun interface for testing purposes - * - * @param linkAddrs an array of LinkAddresses to assign to the TUN interface - * @return A ParcelFileDescriptor of the underlying TUN interface. Close this to tear down the - * TUN interface. - * @hide - */ - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - @NonNull - public TestNetworkInterface createTunInterface(@NonNull Collection<LinkAddress> linkAddrs) { - try { - final LinkAddress[] arr = new LinkAddress[linkAddrs.size()]; - return mService.createTunInterface(linkAddrs.toArray(arr)); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Create a tap interface for testing purposes - * - * @return A ParcelFileDescriptor of the underlying TAP interface. Close this to tear down the - * TAP interface. - * @hide - */ - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - @NonNull - public TestNetworkInterface createTapInterface() { - try { - return mService.createTapInterface(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - -} diff --git a/core/java/android/net/TransportInfo.java b/core/java/android/net/TransportInfo.java deleted file mode 100644 index aa4bbb051179..000000000000 --- a/core/java/android/net/TransportInfo.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.annotation.NonNull; -import android.annotation.SystemApi; - -/** - * A container for transport-specific capabilities which is returned by - * {@link NetworkCapabilities#getTransportInfo()}. Specific networks - * may provide concrete implementations of this interface. - * @see android.net.wifi.aware.WifiAwareNetworkInfo - * @see android.net.wifi.WifiInfo - */ -public interface TransportInfo { - - /** - * Create a copy of a {@link TransportInfo} that will preserve location sensitive fields that - * were set based on the permissions of the process that originally received it. - * - * <p>By default {@link TransportInfo} does not preserve such fields during parceling, as - * they should not be shared outside of the process that receives them without appropriate - * checks. - * - * @param parcelLocationSensitiveFields Whether the location sensitive fields should be kept - * when parceling - * @return Copy of this instance. - * @hide - */ - @SystemApi - @NonNull - default TransportInfo makeCopy(boolean parcelLocationSensitiveFields) { - return this; - } - - /** - * Returns whether this TransportInfo type has location sensitive fields or not (helps - * to determine whether to perform a location permission check or not before sending to - * apps). - * - * @return {@code true} if this instance contains location sensitive info, {@code false} - * otherwise. - * @hide - */ - @SystemApi - default boolean hasLocationSensitiveFields() { - return false; - } -} diff --git a/core/java/android/net/UidRange.aidl b/core/java/android/net/UidRange.aidl deleted file mode 100644 index f70fc8e2fefd..000000000000 --- a/core/java/android/net/UidRange.aidl +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -/** - * An inclusive range of UIDs. - * - * {@hide} - */ -parcelable UidRange;
\ No newline at end of file diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java deleted file mode 100644 index c87b8279c4d6..000000000000 --- a/core/java/android/net/VpnManager.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static com.android.internal.util.Preconditions.checkNotNull; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.Activity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; -import android.os.RemoteException; - -import com.android.internal.net.VpnProfile; - -import java.io.IOException; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.security.GeneralSecurityException; - -/** - * This class provides an interface for apps to manage platform VPN profiles - * - * <p>Apps can use this API to provide profiles with which the platform can set up a VPN without - * further app intermediation. When a VPN profile is present and the app is selected as an always-on - * VPN, the platform will directly trigger the negotiation of the VPN without starting or waking the - * app (unlike VpnService). - * - * <p>VPN apps using supported protocols should preferentially use this API over the {@link - * VpnService} API for ease-of-development and reduced maintainance burden. This also give the user - * the guarantee that VPN network traffic is not subjected to on-device packet interception. - * - * @see Ikev2VpnProfile - */ -public class VpnManager { - /** Type representing a lack of VPN @hide */ - public static final int TYPE_VPN_NONE = -1; - /** VPN service type code @hide */ - public static final int TYPE_VPN_SERVICE = 1; - /** Platform VPN type code @hide */ - public static final int TYPE_VPN_PLATFORM = 2; - - /** @hide */ - @IntDef(value = {TYPE_VPN_NONE, TYPE_VPN_SERVICE, TYPE_VPN_PLATFORM}) - @Retention(RetentionPolicy.SOURCE) - public @interface VpnType {} - - @NonNull private final Context mContext; - @NonNull private final IConnectivityManager mService; - - private static Intent getIntentForConfirmation() { - final Intent intent = new Intent(); - final ComponentName componentName = ComponentName.unflattenFromString( - Resources.getSystem().getString( - com.android.internal.R.string.config_platformVpnConfirmDialogComponent)); - intent.setComponent(componentName); - return intent; - } - - /** - * Create an instance of the VpnManager with the given context. - * - * <p>Internal only. Applications are expected to obtain an instance of the VpnManager via the - * {@link Context.getSystemService()} method call. - * - * @hide - */ - public VpnManager(@NonNull Context ctx, @NonNull IConnectivityManager service) { - mContext = checkNotNull(ctx, "missing Context"); - mService = checkNotNull(service, "missing IConnectivityManager"); - } - - /** - * Install a VpnProfile configuration keyed on the calling app's package name. - * - * <p>This method returns {@code null} if user consent has already been granted, or an {@link - * Intent} to a system activity. If an intent is returned, the application should launch the - * activity using {@link Activity#startActivityForResult} to request user consent. The activity - * may pop up a dialog to require user action, and the result will come back via its {@link - * Activity#onActivityResult}. If the result is {@link Activity#RESULT_OK}, the user has - * consented, and the VPN profile can be started. - * - * @param profile the VpnProfile provided by this package. Will override any previous VpnProfile - * stored for this package. - * @return an Intent requesting user consent to start the VPN, or null if consent is not - * required based on privileges or previous user consent. - */ - @Nullable - public Intent provisionVpnProfile(@NonNull PlatformVpnProfile profile) { - final VpnProfile internalProfile; - - try { - internalProfile = profile.toVpnProfile(); - } catch (GeneralSecurityException | IOException e) { - // Conversion to VpnProfile failed; this is an invalid profile. Both of these exceptions - // indicate a failure to convert a PrivateKey or X509Certificate to a Base64 encoded - // string as required by the VpnProfile. - throw new IllegalArgumentException("Failed to serialize PlatformVpnProfile", e); - } - - try { - // Profile can never be null; it either gets set, or an exception is thrown. - if (mService.provisionVpnProfile(internalProfile, mContext.getOpPackageName())) { - return null; - } - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - return getIntentForConfirmation(); - } - - /** - * Delete the VPN profile configuration that was provisioned by the calling app - * - * @throws SecurityException if this would violate user settings - */ - public void deleteProvisionedVpnProfile() { - try { - mService.deleteVpnProfile(mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Request the startup of a previously provisioned VPN. - * - * @throws SecurityException exception if user or device settings prevent this VPN from being - * setup, or if user consent has not been granted - */ - public void startProvisionedVpnProfile() { - try { - mService.startVpnProfile(mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** Tear down the VPN provided by the calling app (if any) */ - public void stopProvisionedVpnProfile() { - try { - mService.stopVpnProfile(mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } -} diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java deleted file mode 100644 index 8e90a119fe21..000000000000 --- a/core/java/android/net/VpnService.java +++ /dev/null @@ -1,903 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.AF_INET6; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.app.Activity; -import android.app.PendingIntent; -import android.app.Service; -import android.app.admin.DevicePolicyManager; -import android.compat.annotation.UnsupportedAppUsage; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.IPackageManager; -import android.content.pm.PackageManager; -import android.os.Binder; -import android.os.IBinder; -import android.os.Parcel; -import android.os.ParcelFileDescriptor; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.UserHandle; - -import com.android.internal.net.VpnConfig; - -import java.net.DatagramSocket; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.Socket; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -/** - * VpnService is a base class for applications to extend and build their - * own VPN solutions. In general, it creates a virtual network interface, - * configures addresses and routing rules, and returns a file descriptor - * to the application. Each read from the descriptor retrieves an outgoing - * packet which was routed to the interface. Each write to the descriptor - * injects an incoming packet just like it was received from the interface. - * The interface is running on Internet Protocol (IP), so packets are - * always started with IP headers. The application then completes a VPN - * connection by processing and exchanging packets with the remote server - * over a tunnel. - * - * <p>Letting applications intercept packets raises huge security concerns. - * A VPN application can easily break the network. Besides, two of them may - * conflict with each other. The system takes several actions to address - * these issues. Here are some key points: - * <ul> - * <li>User action is required the first time an application creates a VPN - * connection.</li> - * <li>There can be only one VPN connection running at the same time. The - * existing interface is deactivated when a new one is created.</li> - * <li>A system-managed notification is shown during the lifetime of a - * VPN connection.</li> - * <li>A system-managed dialog gives the information of the current VPN - * connection. It also provides a button to disconnect.</li> - * <li>The network is restored automatically when the file descriptor is - * closed. It also covers the cases when a VPN application is crashed - * or killed by the system.</li> - * </ul> - * - * <p>There are two primary methods in this class: {@link #prepare} and - * {@link Builder#establish}. The former deals with user action and stops - * the VPN connection created by another application. The latter creates - * a VPN interface using the parameters supplied to the {@link Builder}. - * An application must call {@link #prepare} to grant the right to use - * other methods in this class, and the right can be revoked at any time. - * Here are the general steps to create a VPN connection: - * <ol> - * <li>When the user presses the button to connect, call {@link #prepare} - * and launch the returned intent, if non-null.</li> - * <li>When the application becomes prepared, start the service.</li> - * <li>Create a tunnel to the remote server and negotiate the network - * parameters for the VPN connection.</li> - * <li>Supply those parameters to a {@link Builder} and create a VPN - * interface by calling {@link Builder#establish}.</li> - * <li>Process and exchange packets between the tunnel and the returned - * file descriptor.</li> - * <li>When {@link #onRevoke} is invoked, close the file descriptor and - * shut down the tunnel gracefully.</li> - * </ol> - * - * <p>Services extending this class need to be declared with an appropriate - * permission and intent filter. Their access must be secured by - * {@link android.Manifest.permission#BIND_VPN_SERVICE} permission, and - * their intent filter must match {@link #SERVICE_INTERFACE} action. Here - * is an example of declaring a VPN service in {@code AndroidManifest.xml}: - * <pre> - * <service android:name=".ExampleVpnService" - * android:permission="android.permission.BIND_VPN_SERVICE"> - * <intent-filter> - * <action android:name="android.net.VpnService"/> - * </intent-filter> - * </service></pre> - * - * <p> The Android system starts a VPN in the background by calling - * {@link android.content.Context#startService startService()}. In Android 8.0 - * (API level 26) and higher, the system places VPN apps on the temporary - * allowlist for a short period so the app can start in the background. The VPN - * app must promote itself to the foreground after it's launched or the system - * will shut down the app. - * - * <h3>Developer's guide</h3> - * - * <p>To learn more about developing VPN apps, read the - * <a href="{@docRoot}guide/topics/connectivity/vpn">VPN developer's guide</a>. - * - * @see Builder - */ -public class VpnService extends Service { - - /** - * The action must be matched by the intent filter of this service. It also - * needs to require {@link android.Manifest.permission#BIND_VPN_SERVICE} - * permission so that other applications cannot abuse it. - */ - public static final String SERVICE_INTERFACE = VpnConfig.SERVICE_INTERFACE; - - /** - * Key for boolean meta-data field indicating whether this VpnService supports always-on mode. - * - * <p>For a VPN app targeting {@link android.os.Build.VERSION_CODES#N API 24} or above, Android - * provides users with the ability to set it as always-on, so that VPN connection is - * persisted after device reboot and app upgrade. Always-on VPN can also be enabled by device - * owner and profile owner apps through - * {@link DevicePolicyManager#setAlwaysOnVpnPackage}. - * - * <p>VPN apps not supporting this feature should opt out by adding this meta-data field to the - * {@code VpnService} component of {@code AndroidManifest.xml}. In case there is more than one - * {@code VpnService} component defined in {@code AndroidManifest.xml}, opting out any one of - * them will opt out the entire app. For example, - * <pre> {@code - * <service android:name=".ExampleVpnService" - * android:permission="android.permission.BIND_VPN_SERVICE"> - * <intent-filter> - * <action android:name="android.net.VpnService"/> - * </intent-filter> - * <meta-data android:name="android.net.VpnService.SUPPORTS_ALWAYS_ON" - * android:value=false/> - * </service> - * } </pre> - * - * <p>This meta-data field defaults to {@code true} if absent. It will only have effect on - * {@link android.os.Build.VERSION_CODES#O_MR1} or higher. - */ - public static final String SERVICE_META_DATA_SUPPORTS_ALWAYS_ON = - "android.net.VpnService.SUPPORTS_ALWAYS_ON"; - - /** - * Use IConnectivityManager since those methods are hidden and not - * available in ConnectivityManager. - */ - private static IConnectivityManager getService() { - return IConnectivityManager.Stub.asInterface( - ServiceManager.getService(Context.CONNECTIVITY_SERVICE)); - } - - /** - * Prepare to establish a VPN connection. This method returns {@code null} - * if the VPN application is already prepared or if the user has previously - * consented to the VPN application. Otherwise, it returns an - * {@link Intent} to a system activity. The application should launch the - * activity using {@link Activity#startActivityForResult} to get itself - * prepared. The activity may pop up a dialog to require user action, and - * the result will come back via its {@link Activity#onActivityResult}. - * If the result is {@link Activity#RESULT_OK}, the application becomes - * prepared and is granted to use other methods in this class. - * - * <p>Only one application can be granted at the same time. The right - * is revoked when another application is granted. The application - * losing the right will be notified via its {@link #onRevoke}. Unless - * it becomes prepared again, subsequent calls to other methods in this - * class will fail. - * - * <p>The user may disable the VPN at any time while it is activated, in - * which case this method will return an intent the next time it is - * executed to obtain the user's consent again. - * - * @see #onRevoke - */ - public static Intent prepare(Context context) { - try { - if (getService().prepareVpn(context.getPackageName(), null, context.getUserId())) { - return null; - } - } catch (RemoteException e) { - // ignore - } - return VpnConfig.getIntentForConfirmation(); - } - - /** - * Version of {@link #prepare(Context)} which does not require user consent. - * - * <p>Requires {@link android.Manifest.permission#CONTROL_VPN} and should generally not be - * used. Only acceptable in situations where user consent has been obtained through other means. - * - * <p>Once this is run, future preparations may be done with the standard prepare method as this - * will authorize the package to prepare the VPN without consent in the future. - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.CONTROL_VPN) - public static void prepareAndAuthorize(Context context) { - IConnectivityManager cm = getService(); - String packageName = context.getPackageName(); - try { - // Only prepare if we're not already prepared. - int userId = context.getUserId(); - if (!cm.prepareVpn(packageName, null, userId)) { - cm.prepareVpn(null, packageName, userId); - } - cm.setVpnPackageAuthorization(packageName, userId, VpnManager.TYPE_VPN_SERVICE); - } catch (RemoteException e) { - // ignore - } - } - - /** - * Protect a socket from VPN connections. After protecting, data sent - * through this socket will go directly to the underlying network, - * so its traffic will not be forwarded through the VPN. - * This method is useful if some connections need to be kept - * outside of VPN. For example, a VPN tunnel should protect itself if its - * destination is covered by VPN routes. Otherwise its outgoing packets - * will be sent back to the VPN interface and cause an infinite loop. This - * method will fail if the application is not prepared or is revoked. - * - * <p class="note">The socket is NOT closed by this method. - * - * @return {@code true} on success. - */ - public boolean protect(int socket) { - return NetworkUtils.protectFromVpn(socket); - } - - /** - * Convenience method to protect a {@link Socket} from VPN connections. - * - * @return {@code true} on success. - * @see #protect(int) - */ - public boolean protect(Socket socket) { - return protect(socket.getFileDescriptor$().getInt$()); - } - - /** - * Convenience method to protect a {@link DatagramSocket} from VPN - * connections. - * - * @return {@code true} on success. - * @see #protect(int) - */ - public boolean protect(DatagramSocket socket) { - return protect(socket.getFileDescriptor$().getInt$()); - } - - /** - * Adds a network address to the VPN interface. - * - * Both IPv4 and IPv6 addresses are supported. The VPN must already be established. Fails if the - * address is already in use or cannot be assigned to the interface for any other reason. - * - * Adding an address implicitly allows traffic from that address family (i.e., IPv4 or IPv6) to - * be routed over the VPN. @see Builder#allowFamily - * - * @throws IllegalArgumentException if the address is invalid. - * - * @param address The IP address (IPv4 or IPv6) to assign to the VPN interface. - * @param prefixLength The prefix length of the address. - * - * @return {@code true} on success. - * @see Builder#addAddress - * - * @hide - */ - public boolean addAddress(InetAddress address, int prefixLength) { - check(address, prefixLength); - try { - return getService().addVpnAddress(address.getHostAddress(), prefixLength); - } catch (RemoteException e) { - throw new IllegalStateException(e); - } - } - - /** - * Removes a network address from the VPN interface. - * - * Both IPv4 and IPv6 addresses are supported. The VPN must already be established. Fails if the - * address is not assigned to the VPN interface, or if it is the only address assigned (thus - * cannot be removed), or if the address cannot be removed for any other reason. - * - * After removing an address, if there are no addresses, routes or DNS servers of a particular - * address family (i.e., IPv4 or IPv6) configured on the VPN, that <b>DOES NOT</b> block that - * family from being routed. In other words, once an address family has been allowed, it stays - * allowed for the rest of the VPN's session. @see Builder#allowFamily - * - * @throws IllegalArgumentException if the address is invalid. - * - * @param address The IP address (IPv4 or IPv6) to assign to the VPN interface. - * @param prefixLength The prefix length of the address. - * - * @return {@code true} on success. - * - * @hide - */ - public boolean removeAddress(InetAddress address, int prefixLength) { - check(address, prefixLength); - try { - return getService().removeVpnAddress(address.getHostAddress(), prefixLength); - } catch (RemoteException e) { - throw new IllegalStateException(e); - } - } - - /** - * Sets the underlying networks used by the VPN for its upstream connections. - * - * <p>Used by the system to know the actual networks that carry traffic for apps affected by - * this VPN in order to present this information to the user (e.g., via status bar icons). - * - * <p>This method only needs to be called if the VPN has explicitly bound its underlying - * communications channels — such as the socket(s) passed to {@link #protect(int)} — - * to a {@code Network} using APIs such as {@link Network#bindSocket(Socket)} or - * {@link Network#bindSocket(DatagramSocket)}. The VPN should call this method every time - * the set of {@code Network}s it is using changes. - * - * <p>{@code networks} is one of the following: - * <ul> - * <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in - * decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular) - * networks to carry app traffic, but prefers or uses wifi more than mobile, wifi should appear - * first in the array.</li> - * <li><strong>an empty array</strong>: a zero-element array, meaning that the VPN has no - * underlying network connection, and thus, app traffic will not be sent or received.</li> - * <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's - * default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket} - * APIs mentioned above to send traffic over specific channels.</li> - * </ul> - * - * <p>This call will succeed only if the VPN is currently established. For setting this value - * when the VPN has not yet been established, see {@link Builder#setUnderlyingNetworks}. - * - * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers. - * - * @return {@code true} on success. - */ - public boolean setUnderlyingNetworks(Network[] networks) { - try { - return getService().setUnderlyingNetworksForVpn(networks); - } catch (RemoteException e) { - throw new IllegalStateException(e); - } - } - - /** - * Returns whether the service is running in always-on VPN mode. In this mode the system ensures - * that the service is always running by restarting it when necessary, e.g. after reboot. - * - * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean, Set) - */ - public final boolean isAlwaysOn() { - try { - return getService().isCallerCurrentAlwaysOnVpnApp(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns whether the service is running in always-on VPN lockdown mode. In this mode the - * system ensures that the service is always running and that the apps aren't allowed to bypass - * the VPN. - * - * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean, Set) - */ - public final boolean isLockdownEnabled() { - try { - return getService().isCallerCurrentAlwaysOnVpnLockdownApp(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Return the communication interface to the service. This method returns - * {@code null} on {@link Intent}s other than {@link #SERVICE_INTERFACE} - * action. Applications overriding this method must identify the intent - * and return the corresponding interface accordingly. - * - * @see Service#onBind - */ - @Override - public IBinder onBind(Intent intent) { - if (intent != null && SERVICE_INTERFACE.equals(intent.getAction())) { - return new Callback(); - } - return null; - } - - /** - * Invoked when the application is revoked. At this moment, the VPN - * interface is already deactivated by the system. The application should - * close the file descriptor and shut down gracefully. The default - * implementation of this method is calling {@link Service#stopSelf()}. - * - * <p class="note">Calls to this method may not happen on the main thread - * of the process. - * - * @see #prepare - */ - public void onRevoke() { - stopSelf(); - } - - /** - * Use raw Binder instead of AIDL since now there is only one usage. - */ - private class Callback extends Binder { - @Override - protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) { - if (code == IBinder.LAST_CALL_TRANSACTION) { - onRevoke(); - return true; - } - return false; - } - } - - /** - * Private method to validate address and prefixLength. - */ - private static void check(InetAddress address, int prefixLength) { - if (address.isLoopbackAddress()) { - throw new IllegalArgumentException("Bad address"); - } - if (address instanceof Inet4Address) { - if (prefixLength < 0 || prefixLength > 32) { - throw new IllegalArgumentException("Bad prefixLength"); - } - } else if (address instanceof Inet6Address) { - if (prefixLength < 0 || prefixLength > 128) { - throw new IllegalArgumentException("Bad prefixLength"); - } - } else { - throw new IllegalArgumentException("Unsupported family"); - } - } - - /** - * Helper class to create a VPN interface. This class should be always - * used within the scope of the outer {@link VpnService}. - * - * @see VpnService - */ - public class Builder { - - private final VpnConfig mConfig = new VpnConfig(); - @UnsupportedAppUsage - private final List<LinkAddress> mAddresses = new ArrayList<LinkAddress>(); - @UnsupportedAppUsage - private final List<RouteInfo> mRoutes = new ArrayList<RouteInfo>(); - - public Builder() { - mConfig.user = VpnService.this.getClass().getName(); - } - - /** - * Set the name of this session. It will be displayed in - * system-managed dialogs and notifications. This is recommended - * not required. - */ - @NonNull - public Builder setSession(@NonNull String session) { - mConfig.session = session; - return this; - } - - /** - * Set the {@link PendingIntent} to an activity for users to - * configure the VPN connection. If it is not set, the button - * to configure will not be shown in system-managed dialogs. - */ - @NonNull - public Builder setConfigureIntent(@NonNull PendingIntent intent) { - mConfig.configureIntent = intent; - return this; - } - - /** - * Set the maximum transmission unit (MTU) of the VPN interface. If - * it is not set, the default value in the operating system will be - * used. - * - * @throws IllegalArgumentException if the value is not positive. - */ - @NonNull - public Builder setMtu(int mtu) { - if (mtu <= 0) { - throw new IllegalArgumentException("Bad mtu"); - } - mConfig.mtu = mtu; - return this; - } - - /** - * Sets an HTTP proxy for the VPN network. This proxy is only a recommendation - * and it is possible that some apps will ignore it. - */ - @NonNull - public Builder setHttpProxy(@NonNull ProxyInfo proxyInfo) { - mConfig.proxyInfo = proxyInfo; - return this; - } - - /** - * Add a network address to the VPN interface. Both IPv4 and IPv6 - * addresses are supported. At least one address must be set before - * calling {@link #establish}. - * - * Adding an address implicitly allows traffic from that address family - * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily - * - * @throws IllegalArgumentException if the address is invalid. - */ - @NonNull - public Builder addAddress(@NonNull InetAddress address, int prefixLength) { - check(address, prefixLength); - - if (address.isAnyLocalAddress()) { - throw new IllegalArgumentException("Bad address"); - } - mAddresses.add(new LinkAddress(address, prefixLength)); - mConfig.updateAllowedFamilies(address); - return this; - } - - /** - * Convenience method to add a network address to the VPN interface - * using a numeric address string. See {@link InetAddress} for the - * definitions of numeric address formats. - * - * Adding an address implicitly allows traffic from that address family - * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily - * - * @throws IllegalArgumentException if the address is invalid. - * @see #addAddress(InetAddress, int) - */ - @NonNull - public Builder addAddress(@NonNull String address, int prefixLength) { - return addAddress(InetAddress.parseNumericAddress(address), prefixLength); - } - - /** - * Add a network route to the VPN interface. Both IPv4 and IPv6 - * routes are supported. - * - * Adding a route implicitly allows traffic from that address family - * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily - * - * @throws IllegalArgumentException if the route is invalid. - */ - @NonNull - public Builder addRoute(@NonNull InetAddress address, int prefixLength) { - check(address, prefixLength); - - int offset = prefixLength / 8; - byte[] bytes = address.getAddress(); - if (offset < bytes.length) { - for (bytes[offset] <<= prefixLength % 8; offset < bytes.length; ++offset) { - if (bytes[offset] != 0) { - throw new IllegalArgumentException("Bad address"); - } - } - } - mRoutes.add(new RouteInfo(new IpPrefix(address, prefixLength), null)); - mConfig.updateAllowedFamilies(address); - return this; - } - - /** - * Convenience method to add a network route to the VPN interface - * using a numeric address string. See {@link InetAddress} for the - * definitions of numeric address formats. - * - * Adding a route implicitly allows traffic from that address family - * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily - * - * @throws IllegalArgumentException if the route is invalid. - * @see #addRoute(InetAddress, int) - */ - @NonNull - public Builder addRoute(@NonNull String address, int prefixLength) { - return addRoute(InetAddress.parseNumericAddress(address), prefixLength); - } - - /** - * Add a DNS server to the VPN connection. Both IPv4 and IPv6 - * addresses are supported. If none is set, the DNS servers of - * the default network will be used. - * - * Adding a server implicitly allows traffic from that address family - * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily - * - * @throws IllegalArgumentException if the address is invalid. - */ - @NonNull - public Builder addDnsServer(@NonNull InetAddress address) { - if (address.isLoopbackAddress() || address.isAnyLocalAddress()) { - throw new IllegalArgumentException("Bad address"); - } - if (mConfig.dnsServers == null) { - mConfig.dnsServers = new ArrayList<String>(); - } - mConfig.dnsServers.add(address.getHostAddress()); - return this; - } - - /** - * Convenience method to add a DNS server to the VPN connection - * using a numeric address string. See {@link InetAddress} for the - * definitions of numeric address formats. - * - * Adding a server implicitly allows traffic from that address family - * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily - * - * @throws IllegalArgumentException if the address is invalid. - * @see #addDnsServer(InetAddress) - */ - @NonNull - public Builder addDnsServer(@NonNull String address) { - return addDnsServer(InetAddress.parseNumericAddress(address)); - } - - /** - * Add a search domain to the DNS resolver. - */ - @NonNull - public Builder addSearchDomain(@NonNull String domain) { - if (mConfig.searchDomains == null) { - mConfig.searchDomains = new ArrayList<String>(); - } - mConfig.searchDomains.add(domain); - return this; - } - - /** - * Allows traffic from the specified address family. - * - * By default, if no address, route or DNS server of a specific family (IPv4 or IPv6) is - * added to this VPN, then all outgoing traffic of that family is blocked. If any address, - * route or DNS server is added, that family is allowed. - * - * This method allows an address family to be unblocked even without adding an address, - * route or DNS server of that family. Traffic of that family will then typically - * fall-through to the underlying network if it's supported. - * - * {@code family} must be either {@code AF_INET} (for IPv4) or {@code AF_INET6} (for IPv6). - * {@link IllegalArgumentException} is thrown if it's neither. - * - * @param family The address family ({@code AF_INET} or {@code AF_INET6}) to allow. - * - * @return this {@link Builder} object to facilitate chaining of method calls. - */ - @NonNull - public Builder allowFamily(int family) { - if (family == AF_INET) { - mConfig.allowIPv4 = true; - } else if (family == AF_INET6) { - mConfig.allowIPv6 = true; - } else { - throw new IllegalArgumentException(family + " is neither " + AF_INET + " nor " + - AF_INET6); - } - return this; - } - - private void verifyApp(String packageName) throws PackageManager.NameNotFoundException { - IPackageManager pm = IPackageManager.Stub.asInterface( - ServiceManager.getService("package")); - try { - pm.getApplicationInfo(packageName, 0, UserHandle.getCallingUserId()); - } catch (RemoteException e) { - throw new IllegalStateException(e); - } - } - - /** - * Adds an application that's allowed to access the VPN connection. - * - * If this method is called at least once, only applications added through this method (and - * no others) are allowed access. Else (if this method is never called), all applications - * are allowed by default. If some applications are added, other, un-added applications - * will use networking as if the VPN wasn't running. - * - * A {@link Builder} may have only a set of allowed applications OR a set of disallowed - * ones, but not both. Calling this method after {@link #addDisallowedApplication} has - * already been called, or vice versa, will throw an {@link UnsupportedOperationException}. - * - * {@code packageName} must be the canonical name of a currently installed application. - * {@link PackageManager.NameNotFoundException} is thrown if there's no such application. - * - * @throws PackageManager.NameNotFoundException If the application isn't installed. - * - * @param packageName The full name (e.g.: "com.google.apps.contacts") of an application. - * - * @return this {@link Builder} object to facilitate chaining method calls. - */ - @NonNull - public Builder addAllowedApplication(@NonNull String packageName) - throws PackageManager.NameNotFoundException { - if (mConfig.disallowedApplications != null) { - throw new UnsupportedOperationException("addDisallowedApplication already called"); - } - verifyApp(packageName); - if (mConfig.allowedApplications == null) { - mConfig.allowedApplications = new ArrayList<String>(); - } - mConfig.allowedApplications.add(packageName); - return this; - } - - /** - * Adds an application that's denied access to the VPN connection. - * - * By default, all applications are allowed access, except for those denied through this - * method. Denied applications will use networking as if the VPN wasn't running. - * - * A {@link Builder} may have only a set of allowed applications OR a set of disallowed - * ones, but not both. Calling this method after {@link #addAllowedApplication} has already - * been called, or vice versa, will throw an {@link UnsupportedOperationException}. - * - * {@code packageName} must be the canonical name of a currently installed application. - * {@link PackageManager.NameNotFoundException} is thrown if there's no such application. - * - * @throws PackageManager.NameNotFoundException If the application isn't installed. - * - * @param packageName The full name (e.g.: "com.google.apps.contacts") of an application. - * - * @return this {@link Builder} object to facilitate chaining method calls. - */ - @NonNull - public Builder addDisallowedApplication(@NonNull String packageName) - throws PackageManager.NameNotFoundException { - if (mConfig.allowedApplications != null) { - throw new UnsupportedOperationException("addAllowedApplication already called"); - } - verifyApp(packageName); - if (mConfig.disallowedApplications == null) { - mConfig.disallowedApplications = new ArrayList<String>(); - } - mConfig.disallowedApplications.add(packageName); - return this; - } - - /** - * Allows all apps to bypass this VPN connection. - * - * By default, all traffic from apps is forwarded through the VPN interface and it is not - * possible for apps to side-step the VPN. If this method is called, apps may use methods - * such as {@link ConnectivityManager#bindProcessToNetwork} to instead send/receive - * directly over the underlying network or any other network they have permissions for. - * - * @return this {@link Builder} object to facilitate chaining of method calls. - */ - @NonNull - public Builder allowBypass() { - mConfig.allowBypass = true; - return this; - } - - /** - * Sets the VPN interface's file descriptor to be in blocking/non-blocking mode. - * - * By default, the file descriptor returned by {@link #establish} is non-blocking. - * - * @param blocking True to put the descriptor into blocking mode; false for non-blocking. - * - * @return this {@link Builder} object to facilitate chaining method calls. - */ - @NonNull - public Builder setBlocking(boolean blocking) { - mConfig.blocking = blocking; - return this; - } - - /** - * Sets the underlying networks used by the VPN for its upstream connections. - * - * @see VpnService#setUnderlyingNetworks - * - * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers. - * - * @return this {@link Builder} object to facilitate chaining method calls. - */ - @NonNull - public Builder setUnderlyingNetworks(@Nullable Network[] networks) { - mConfig.underlyingNetworks = networks != null ? networks.clone() : null; - return this; - } - - /** - * Marks the VPN network as metered. A VPN network is classified as metered when the user is - * sensitive to heavy data usage due to monetary costs and/or data limitations. In such - * cases, you should set this to {@code true} so that apps on the system can avoid doing - * large data transfers. Otherwise, set this to {@code false}. Doing so would cause VPN - * network to inherit its meteredness from its underlying networks. - * - * <p>VPN apps targeting {@link android.os.Build.VERSION_CODES#Q} or above will be - * considered metered by default. - * - * @param isMetered {@code true} if VPN network should be treated as metered regardless of - * underlying network meteredness - * @return this {@link Builder} object to facilitate chaining method calls - * @see #setUnderlyingNetworks(Network[]) - * @see ConnectivityManager#isActiveNetworkMetered() - */ - @NonNull - public Builder setMetered(boolean isMetered) { - mConfig.isMetered = isMetered; - return this; - } - - /** - * Create a VPN interface using the parameters supplied to this - * builder. The interface works on IP packets, and a file descriptor - * is returned for the application to access them. Each read - * retrieves an outgoing packet which was routed to the interface. - * Each write injects an incoming packet just like it was received - * from the interface. The file descriptor is put into non-blocking - * mode by default to avoid blocking Java threads. To use the file - * descriptor completely in native space, see - * {@link ParcelFileDescriptor#detachFd()}. The application MUST - * close the file descriptor when the VPN connection is terminated. - * The VPN interface will be removed and the network will be - * restored by the system automatically. - * - * <p>To avoid conflicts, there can be only one active VPN interface - * at the same time. Usually network parameters are never changed - * during the lifetime of a VPN connection. It is also common for an - * application to create a new file descriptor after closing the - * previous one. However, it is rare but not impossible to have two - * interfaces while performing a seamless handover. In this case, the - * old interface will be deactivated when the new one is created - * successfully. Both file descriptors are valid but now outgoing - * packets will be routed to the new interface. Therefore, after - * draining the old file descriptor, the application MUST close it - * and start using the new file descriptor. If the new interface - * cannot be created, the existing interface and its file descriptor - * remain untouched. - * - * <p>An exception will be thrown if the interface cannot be created - * for any reason. However, this method returns {@code null} if the - * application is not prepared or is revoked. This helps solve - * possible race conditions between other VPN applications. - * - * @return {@link ParcelFileDescriptor} of the VPN interface, or - * {@code null} if the application is not prepared. - * @throws IllegalArgumentException if a parameter is not accepted - * by the operating system. - * @throws IllegalStateException if a parameter cannot be applied - * by the operating system. - * @throws SecurityException if the service is not properly declared - * in {@code AndroidManifest.xml}. - * @see VpnService - */ - @Nullable - public ParcelFileDescriptor establish() { - mConfig.addresses = mAddresses; - mConfig.routes = mRoutes; - - try { - return getService().establishVpn(mConfig); - } catch (RemoteException e) { - throw new IllegalStateException(e); - } - } - } -} diff --git a/core/java/android/net/apf/ApfCapabilities.aidl b/core/java/android/net/apf/ApfCapabilities.aidl deleted file mode 100644 index 7c4d4c2da4bc..000000000000 --- a/core/java/android/net/apf/ApfCapabilities.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* -** -** Copyright (C) 2019 The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -package android.net.apf; - -@JavaOnlyStableParcelable parcelable ApfCapabilities;
\ No newline at end of file diff --git a/core/java/android/net/apf/ApfCapabilities.java b/core/java/android/net/apf/ApfCapabilities.java deleted file mode 100644 index bf5b26e278f9..000000000000 --- a/core/java/android/net/apf/ApfCapabilities.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.apf; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.content.res.Resources; -import android.os.Parcel; -import android.os.Parcelable; - -import com.android.internal.R; - -/** - * APF program support capabilities. APF stands for Android Packet Filtering and it is a flexible - * way to drop unwanted network packets to save power. - * - * See documentation at hardware/google/apf/apf.h - * - * This class is immutable. - * @hide - */ -@SystemApi -public final class ApfCapabilities implements Parcelable { - /** - * Version of APF instruction set supported for packet filtering. 0 indicates no support for - * packet filtering using APF programs. - */ - public final int apfVersionSupported; - - /** - * Maximum size of APF program allowed. - */ - public final int maximumApfProgramSize; - - /** - * Format of packets passed to APF filter. Should be one of ARPHRD_* - */ - public final int apfPacketFormat; - - public ApfCapabilities( - int apfVersionSupported, int maximumApfProgramSize, int apfPacketFormat) { - this.apfVersionSupported = apfVersionSupported; - this.maximumApfProgramSize = maximumApfProgramSize; - this.apfPacketFormat = apfPacketFormat; - } - - private ApfCapabilities(Parcel in) { - apfVersionSupported = in.readInt(); - maximumApfProgramSize = in.readInt(); - apfPacketFormat = in.readInt(); - } - - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(apfVersionSupported); - dest.writeInt(maximumApfProgramSize); - dest.writeInt(apfPacketFormat); - } - - public static final Creator<ApfCapabilities> CREATOR = new Creator<ApfCapabilities>() { - @Override - public ApfCapabilities createFromParcel(Parcel in) { - return new ApfCapabilities(in); - } - - @Override - public ApfCapabilities[] newArray(int size) { - return new ApfCapabilities[size]; - } - }; - - @NonNull - @Override - public String toString() { - return String.format("%s{version: %d, maxSize: %d, format: %d}", getClass().getSimpleName(), - apfVersionSupported, maximumApfProgramSize, apfPacketFormat); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (!(obj instanceof ApfCapabilities)) return false; - final ApfCapabilities other = (ApfCapabilities) obj; - return apfVersionSupported == other.apfVersionSupported - && maximumApfProgramSize == other.maximumApfProgramSize - && apfPacketFormat == other.apfPacketFormat; - } - - /** - * Determines whether the APF interpreter advertises support for the data buffer access opcodes - * LDDW (LoaD Data Word) and STDW (STore Data Word). Full LDDW (LoaD Data Word) and - * STDW (STore Data Word) support is present from APFv4 on. - * - * @return {@code true} if the IWifiStaIface#readApfPacketFilterData is supported. - */ - public boolean hasDataAccess() { - return apfVersionSupported >= 4; - } - - /** - * @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames. - */ - public static boolean getApfDrop8023Frames() { - return Resources.getSystem().getBoolean(R.bool.config_apfDrop802_3Frames); - } - - /** - * @return An array of denylisted EtherType, packets with EtherTypes within it will be dropped. - */ - public static @NonNull int[] getApfEtherTypeBlackList() { - return Resources.getSystem().getIntArray(R.array.config_apfEthTypeBlackList); - } -} diff --git a/core/java/android/net/util/DnsUtils.java b/core/java/android/net/util/DnsUtils.java deleted file mode 100644 index 7908353eeda2..000000000000 --- a/core/java/android/net/util/DnsUtils.java +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.util; - -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.AF_INET6; -import static android.system.OsConstants.IPPROTO_UDP; -import static android.system.OsConstants.SOCK_DGRAM; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.net.InetAddresses; -import android.net.Network; -import android.system.ErrnoException; -import android.system.Os; -import android.util.Log; - -import com.android.internal.util.BitUtils; - -import libcore.io.IoUtils; - -import java.io.FileDescriptor; -import java.io.IOException; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -/** - * @hide - */ -public class DnsUtils { - private static final String TAG = "DnsUtils"; - private static final int CHAR_BIT = 8; - public static final int IPV6_ADDR_SCOPE_NODELOCAL = 0x01; - public static final int IPV6_ADDR_SCOPE_LINKLOCAL = 0x02; - public static final int IPV6_ADDR_SCOPE_SITELOCAL = 0x05; - public static final int IPV6_ADDR_SCOPE_GLOBAL = 0x0e; - private static final Comparator<SortableAddress> sRfc6724Comparator = new Rfc6724Comparator(); - - /** - * Comparator to sort SortableAddress in Rfc6724 style. - */ - public static class Rfc6724Comparator implements Comparator<SortableAddress> { - // This function matches the behaviour of _rfc6724_compare in the native resolver. - @Override - public int compare(SortableAddress span1, SortableAddress span2) { - // Rule 1: Avoid unusable destinations. - if (span1.hasSrcAddr != span2.hasSrcAddr) { - return span2.hasSrcAddr - span1.hasSrcAddr; - } - - // Rule 2: Prefer matching scope. - if (span1.scopeMatch != span2.scopeMatch) { - return span2.scopeMatch - span1.scopeMatch; - } - - // TODO: Implement rule 3: Avoid deprecated addresses. - // TODO: Implement rule 4: Prefer home addresses. - - // Rule 5: Prefer matching label. - if (span1.labelMatch != span2.labelMatch) { - return span2.labelMatch - span1.labelMatch; - } - - // Rule 6: Prefer higher precedence. - if (span1.precedence != span2.precedence) { - return span2.precedence - span1.precedence; - } - - // TODO: Implement rule 7: Prefer native transport. - - // Rule 8: Prefer smaller scope. - if (span1.scope != span2.scope) { - return span1.scope - span2.scope; - } - - // Rule 9: Use longest matching prefix. IPv6 only. - if (span1.prefixMatchLen != span2.prefixMatchLen) { - return span2.prefixMatchLen - span1.prefixMatchLen; - } - - // Rule 10: Leave the order unchanged. Collections.sort is a stable sort. - return 0; - } - } - - /** - * Class used to sort with RFC 6724 - */ - public static class SortableAddress { - public final int label; - public final int labelMatch; - public final int scope; - public final int scopeMatch; - public final int precedence; - public final int prefixMatchLen; - public final int hasSrcAddr; - public final InetAddress address; - - public SortableAddress(@NonNull InetAddress addr, @Nullable InetAddress srcAddr) { - address = addr; - hasSrcAddr = (srcAddr != null) ? 1 : 0; - label = findLabel(addr); - scope = findScope(addr); - precedence = findPrecedence(addr); - labelMatch = ((srcAddr != null) && (label == findLabel(srcAddr))) ? 1 : 0; - scopeMatch = ((srcAddr != null) && (scope == findScope(srcAddr))) ? 1 : 0; - if (isIpv6Address(addr) && isIpv6Address(srcAddr)) { - prefixMatchLen = compareIpv6PrefixMatchLen(srcAddr, addr); - } else { - prefixMatchLen = 0; - } - } - } - - /** - * Sort the given address list in RFC6724 order. - * Will leave the list unchanged if an error occurs. - * - * This function matches the behaviour of _rfc6724_sort in the native resolver. - */ - public static @NonNull List<InetAddress> rfc6724Sort(@Nullable Network network, - @NonNull List<InetAddress> answers) { - final ArrayList<SortableAddress> sortableAnswerList = new ArrayList<>(); - for (InetAddress addr : answers) { - sortableAnswerList.add(new SortableAddress(addr, findSrcAddress(network, addr))); - } - - Collections.sort(sortableAnswerList, sRfc6724Comparator); - - final List<InetAddress> sortedAnswers = new ArrayList<>(); - for (SortableAddress ans : sortableAnswerList) { - sortedAnswers.add(ans.address); - } - - return sortedAnswers; - } - - private static @Nullable InetAddress findSrcAddress(@Nullable Network network, - @NonNull InetAddress addr) { - final int domain; - if (isIpv4Address(addr)) { - domain = AF_INET; - } else if (isIpv6Address(addr)) { - domain = AF_INET6; - } else { - return null; - } - final FileDescriptor socket; - try { - socket = Os.socket(domain, SOCK_DGRAM, IPPROTO_UDP); - } catch (ErrnoException e) { - Log.e(TAG, "findSrcAddress:" + e.toString()); - return null; - } - try { - if (network != null) network.bindSocket(socket); - Os.connect(socket, new InetSocketAddress(addr, 0)); - return ((InetSocketAddress) Os.getsockname(socket)).getAddress(); - } catch (IOException | ErrnoException e) { - return null; - } finally { - IoUtils.closeQuietly(socket); - } - } - - /** - * Get the label for a given IPv4/IPv6 address. - * RFC 6724, section 2.1. - * - * Note that Java will return an IPv4-mapped address as an IPv4 address. - */ - private static int findLabel(@NonNull InetAddress addr) { - if (isIpv4Address(addr)) { - return 4; - } else if (isIpv6Address(addr)) { - if (addr.isLoopbackAddress()) { - return 0; - } else if (isIpv6Address6To4(addr)) { - return 2; - } else if (isIpv6AddressTeredo(addr)) { - return 5; - } else if (isIpv6AddressULA(addr)) { - return 13; - } else if (((Inet6Address) addr).isIPv4CompatibleAddress()) { - return 3; - } else if (addr.isSiteLocalAddress()) { - return 11; - } else if (isIpv6Address6Bone(addr)) { - return 12; - } else { - // All other IPv6 addresses, including global unicast addresses. - return 1; - } - } else { - // This should never happen. - return 1; - } - } - - private static boolean isIpv6Address(@Nullable InetAddress addr) { - return addr instanceof Inet6Address; - } - - private static boolean isIpv4Address(@Nullable InetAddress addr) { - return addr instanceof Inet4Address; - } - - private static boolean isIpv6Address6To4(@NonNull InetAddress addr) { - if (!isIpv6Address(addr)) return false; - final byte[] byteAddr = addr.getAddress(); - return byteAddr[0] == 0x20 && byteAddr[1] == 0x02; - } - - private static boolean isIpv6AddressTeredo(@NonNull InetAddress addr) { - if (!isIpv6Address(addr)) return false; - final byte[] byteAddr = addr.getAddress(); - return byteAddr[0] == 0x20 && byteAddr[1] == 0x01 && byteAddr[2] == 0x00 - && byteAddr[3] == 0x00; - } - - private static boolean isIpv6AddressULA(@NonNull InetAddress addr) { - return isIpv6Address(addr) && (addr.getAddress()[0] & 0xfe) == 0xfc; - } - - private static boolean isIpv6Address6Bone(@NonNull InetAddress addr) { - if (!isIpv6Address(addr)) return false; - final byte[] byteAddr = addr.getAddress(); - return byteAddr[0] == 0x3f && byteAddr[1] == (byte) 0xfe; - } - - private static int getIpv6MulticastScope(@NonNull InetAddress addr) { - return !isIpv6Address(addr) ? 0 : (addr.getAddress()[1] & 0x0f); - } - - private static int findScope(@NonNull InetAddress addr) { - if (isIpv6Address(addr)) { - if (addr.isMulticastAddress()) { - return getIpv6MulticastScope(addr); - } else if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) { - /** - * RFC 4291 section 2.5.3 says loopback is to be treated as having - * link-local scope. - */ - return IPV6_ADDR_SCOPE_LINKLOCAL; - } else if (addr.isSiteLocalAddress()) { - return IPV6_ADDR_SCOPE_SITELOCAL; - } else { - return IPV6_ADDR_SCOPE_GLOBAL; - } - } else if (isIpv4Address(addr)) { - if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) { - return IPV6_ADDR_SCOPE_LINKLOCAL; - } else { - /** - * RFC 6724 section 3.2. Other IPv4 addresses, including private addresses - * and shared addresses (100.64.0.0/10), are assigned global scope. - */ - return IPV6_ADDR_SCOPE_GLOBAL; - } - } else { - /** - * This should never happen. - * Return a scope with low priority as a last resort. - */ - return IPV6_ADDR_SCOPE_NODELOCAL; - } - } - - /** - * Get the precedence for a given IPv4/IPv6 address. - * RFC 6724, section 2.1. - * - * Note that Java will return an IPv4-mapped address as an IPv4 address. - */ - private static int findPrecedence(@NonNull InetAddress addr) { - if (isIpv4Address(addr)) { - return 35; - } else if (isIpv6Address(addr)) { - if (addr.isLoopbackAddress()) { - return 50; - } else if (isIpv6Address6To4(addr)) { - return 30; - } else if (isIpv6AddressTeredo(addr)) { - return 5; - } else if (isIpv6AddressULA(addr)) { - return 3; - } else if (((Inet6Address) addr).isIPv4CompatibleAddress() || addr.isSiteLocalAddress() - || isIpv6Address6Bone(addr)) { - return 1; - } else { - // All other IPv6 addresses, including global unicast addresses. - return 40; - } - } else { - return 1; - } - } - - /** - * Find number of matching initial bits between the two addresses. - */ - private static int compareIpv6PrefixMatchLen(@NonNull InetAddress srcAddr, - @NonNull InetAddress dstAddr) { - final byte[] srcByte = srcAddr.getAddress(); - final byte[] dstByte = dstAddr.getAddress(); - - // This should never happen. - if (srcByte.length != dstByte.length) return 0; - - for (int i = 0; i < dstByte.length; ++i) { - if (srcByte[i] == dstByte[i]) { - continue; - } - int x = BitUtils.uint8(srcByte[i]) ^ BitUtils.uint8(dstByte[i]); - return i * CHAR_BIT + (Integer.numberOfLeadingZeros(x) - 24); // Java ints are 32 bits - } - return dstByte.length * CHAR_BIT; - } - - /** - * Check if given network has Ipv4 capability - * This function matches the behaviour of have_ipv4 in the native resolver. - */ - public static boolean haveIpv4(@Nullable Network network) { - final SocketAddress addrIpv4 = - new InetSocketAddress(InetAddresses.parseNumericAddress("8.8.8.8"), 0); - return checkConnectivity(network, AF_INET, addrIpv4); - } - - /** - * Check if given network has Ipv6 capability - * This function matches the behaviour of have_ipv6 in the native resolver. - */ - public static boolean haveIpv6(@Nullable Network network) { - final SocketAddress addrIpv6 = - new InetSocketAddress(InetAddresses.parseNumericAddress("2000::"), 0); - return checkConnectivity(network, AF_INET6, addrIpv6); - } - - private static boolean checkConnectivity(@Nullable Network network, - int domain, @NonNull SocketAddress addr) { - final FileDescriptor socket; - try { - socket = Os.socket(domain, SOCK_DGRAM, IPPROTO_UDP); - } catch (ErrnoException e) { - return false; - } - try { - if (network != null) network.bindSocket(socket); - Os.connect(socket, addr); - } catch (IOException | ErrnoException e) { - return false; - } finally { - IoUtils.closeQuietly(socket); - } - return true; - } -} diff --git a/core/java/android/net/util/KeepaliveUtils.java b/core/java/android/net/util/KeepaliveUtils.java deleted file mode 100644 index bfc4563fbf8f..000000000000 --- a/core/java/android/net/util/KeepaliveUtils.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.util; - -import android.annotation.NonNull; -import android.content.Context; -import android.content.res.Resources; -import android.net.NetworkCapabilities; -import android.text.TextUtils; -import android.util.AndroidRuntimeException; - -import com.android.internal.R; - -/** - * Collection of utilities for socket keepalive offload. - * - * @hide - */ -public final class KeepaliveUtils { - - public static final String TAG = "KeepaliveUtils"; - - public static class KeepaliveDeviceConfigurationException extends AndroidRuntimeException { - public KeepaliveDeviceConfigurationException(final String msg) { - super(msg); - } - } - - /** - * Read supported keepalive count for each transport type from overlay resource. This should be - * used to create a local variable store of resource customization, and use it as the input for - * {@link getSupportedKeepalivesForNetworkCapabilities}. - * - * @param context The context to read resource from. - * @return An array of supported keepalive count for each transport type. - */ - @NonNull - public static int[] getSupportedKeepalives(@NonNull Context context) { - String[] res = null; - try { - res = context.getResources().getStringArray( - R.array.config_networkSupportedKeepaliveCount); - } catch (Resources.NotFoundException unused) { - } - if (res == null) throw new KeepaliveDeviceConfigurationException("invalid resource"); - - final int[] ret = new int[NetworkCapabilities.MAX_TRANSPORT + 1]; - for (final String row : res) { - if (TextUtils.isEmpty(row)) { - throw new KeepaliveDeviceConfigurationException("Empty string"); - } - final String[] arr = row.split(","); - if (arr.length != 2) { - throw new KeepaliveDeviceConfigurationException("Invalid parameter length"); - } - - int transport; - int supported; - try { - transport = Integer.parseInt(arr[0]); - supported = Integer.parseInt(arr[1]); - } catch (NumberFormatException e) { - throw new KeepaliveDeviceConfigurationException("Invalid number format"); - } - - if (!NetworkCapabilities.isValidTransport(transport)) { - throw new KeepaliveDeviceConfigurationException("Invalid transport " + transport); - } - - if (supported < 0) { - throw new KeepaliveDeviceConfigurationException( - "Invalid supported count " + supported + " for " - + NetworkCapabilities.transportNameOf(transport)); - } - ret[transport] = supported; - } - return ret; - } - - /** - * Get supported keepalive count for the given {@link NetworkCapabilities}. - * - * @param supportedKeepalives An array of supported keepalive count for each transport type. - * @param nc The {@link NetworkCapabilities} of the network the socket keepalive is on. - * - * @return Supported keepalive count for the given {@link NetworkCapabilities}. - */ - public static int getSupportedKeepalivesForNetworkCapabilities( - @NonNull int[] supportedKeepalives, @NonNull NetworkCapabilities nc) { - final int[] transports = nc.getTransportTypes(); - if (transports.length == 0) return 0; - int supportedCount = supportedKeepalives[transports[0]]; - // Iterate through transports and return minimum supported value. - for (final int transport : transports) { - if (supportedCount > supportedKeepalives[transport]) { - supportedCount = supportedKeepalives[transport]; - } - } - return supportedCount; - } -} diff --git a/core/java/android/net/util/MultinetworkPolicyTracker.java b/core/java/android/net/util/MultinetworkPolicyTracker.java deleted file mode 100644 index 85e3fa3048ed..000000000000 --- a/core/java/android/net/util/MultinetworkPolicyTracker.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.util; - -import static android.provider.Settings.Global.NETWORK_AVOID_BAD_WIFI; -import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE; - -import android.annotation.NonNull; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.res.Resources; -import android.database.ContentObserver; -import android.net.Uri; -import android.os.Handler; -import android.provider.Settings; -import android.telephony.PhoneStateListener; -import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; -import android.util.Log; - -import com.android.internal.R; -import com.android.internal.annotations.VisibleForTesting; - -import java.util.Arrays; -import java.util.List; - -/** - * A class to encapsulate management of the "Smart Networking" capability of - * avoiding bad Wi-Fi when, for example upstream connectivity is lost or - * certain critical link failures occur. - * - * This enables the device to switch to another form of connectivity, like - * mobile, if it's available and working. - * - * The Runnable |avoidBadWifiCallback|, if given, is posted to the supplied - * Handler' whenever the computed "avoid bad wifi" value changes. - * - * Disabling this reverts the device to a level of networking sophistication - * circa 2012-13 by disabling disparate code paths each of which contribute to - * maintaining continuous, working Internet connectivity. - * - * @hide - */ -public class MultinetworkPolicyTracker { - private static String TAG = MultinetworkPolicyTracker.class.getSimpleName(); - - private final Context mContext; - private final Handler mHandler; - private final Runnable mAvoidBadWifiCallback; - private final List<Uri> mSettingsUris; - private final ContentResolver mResolver; - private final SettingObserver mSettingObserver; - private final BroadcastReceiver mBroadcastReceiver; - - private volatile boolean mAvoidBadWifi = true; - private volatile int mMeteredMultipathPreference; - private int mActiveSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - - public MultinetworkPolicyTracker(Context ctx, Handler handler) { - this(ctx, handler, null); - } - - public MultinetworkPolicyTracker(Context ctx, Handler handler, Runnable avoidBadWifiCallback) { - mContext = ctx; - mHandler = handler; - mAvoidBadWifiCallback = avoidBadWifiCallback; - mSettingsUris = Arrays.asList( - Settings.Global.getUriFor(NETWORK_AVOID_BAD_WIFI), - Settings.Global.getUriFor(NETWORK_METERED_MULTIPATH_PREFERENCE)); - mResolver = mContext.getContentResolver(); - mSettingObserver = new SettingObserver(); - mBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - reevaluateInternal(); - } - }; - - ctx.getSystemService(TelephonyManager.class).listen( - new PhoneStateListener(handler.getLooper()) { - @Override - public void onActiveDataSubscriptionIdChanged(int subId) { - mActiveSubId = subId; - reevaluateInternal(); - } - }, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); - - updateAvoidBadWifi(); - updateMeteredMultipathPreference(); - } - - public void start() { - for (Uri uri : mSettingsUris) { - mResolver.registerContentObserver(uri, false, mSettingObserver); - } - - final IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); - mContext.registerReceiverForAllUsers(mBroadcastReceiver, intentFilter, - null /* broadcastPermission */, mHandler); - - reevaluate(); - } - - public void shutdown() { - mResolver.unregisterContentObserver(mSettingObserver); - - mContext.unregisterReceiver(mBroadcastReceiver); - } - - public boolean getAvoidBadWifi() { - return mAvoidBadWifi; - } - - // TODO: move this to MultipathPolicyTracker. - public int getMeteredMultipathPreference() { - return mMeteredMultipathPreference; - } - - /** - * Whether the device or carrier configuration disables avoiding bad wifi by default. - */ - public boolean configRestrictsAvoidBadWifi() { - return (getResourcesForActiveSubId().getInteger(R.integer.config_networkAvoidBadWifi) == 0); - } - - @NonNull - private Resources getResourcesForActiveSubId() { - return SubscriptionManager.getResourcesForSubId(mContext, mActiveSubId); - } - - /** - * Whether we should display a notification when wifi becomes unvalidated. - */ - public boolean shouldNotifyWifiUnvalidated() { - return configRestrictsAvoidBadWifi() && getAvoidBadWifiSetting() == null; - } - - public String getAvoidBadWifiSetting() { - return Settings.Global.getString(mResolver, NETWORK_AVOID_BAD_WIFI); - } - - @VisibleForTesting - public void reevaluate() { - mHandler.post(this::reevaluateInternal); - } - - /** - * Reevaluate the settings. Must be called on the handler thread. - */ - private void reevaluateInternal() { - if (updateAvoidBadWifi() && mAvoidBadWifiCallback != null) { - mAvoidBadWifiCallback.run(); - } - updateMeteredMultipathPreference(); - } - - public boolean updateAvoidBadWifi() { - final boolean settingAvoidBadWifi = "1".equals(getAvoidBadWifiSetting()); - final boolean prev = mAvoidBadWifi; - mAvoidBadWifi = settingAvoidBadWifi || !configRestrictsAvoidBadWifi(); - return mAvoidBadWifi != prev; - } - - /** - * The default (device and carrier-dependent) value for metered multipath preference. - */ - public int configMeteredMultipathPreference() { - return mContext.getResources().getInteger( - R.integer.config_networkMeteredMultipathPreference); - } - - public void updateMeteredMultipathPreference() { - String setting = Settings.Global.getString(mResolver, NETWORK_METERED_MULTIPATH_PREFERENCE); - try { - mMeteredMultipathPreference = Integer.parseInt(setting); - } catch (NumberFormatException e) { - mMeteredMultipathPreference = configMeteredMultipathPreference(); - } - } - - private class SettingObserver extends ContentObserver { - public SettingObserver() { - super(null); - } - - @Override - public void onChange(boolean selfChange) { - Log.wtf(TAG, "Should never be reached."); - } - - @Override - public void onChange(boolean selfChange, Uri uri) { - if (!mSettingsUris.contains(uri)) { - Log.wtf(TAG, "Unexpected settings observation: " + uri); - } - reevaluate(); - } - } -} diff --git a/core/java/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java deleted file mode 100644 index e64060f1b220..000000000000 --- a/core/java/android/net/util/SocketUtils.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.util; - -import static android.system.OsConstants.SOL_SOCKET; -import static android.system.OsConstants.SO_BINDTODEVICE; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.net.NetworkUtils; -import android.system.ErrnoException; -import android.system.NetlinkSocketAddress; -import android.system.Os; -import android.system.PacketSocketAddress; - -import libcore.io.IoBridge; - -import java.io.FileDescriptor; -import java.io.IOException; -import java.net.SocketAddress; - -/** - * Collection of utilities to interact with raw sockets. - * @hide - */ -@SystemApi -public final class SocketUtils { - /** - * Create a raw datagram socket that is bound to an interface. - * - * <p>Data sent through the socket will go directly to the underlying network, ignoring VPNs. - */ - public static void bindSocketToInterface(@NonNull FileDescriptor socket, @NonNull String iface) - throws ErrnoException { - // SO_BINDTODEVICE actually takes a string. This works because the first member - // of struct ifreq is a NULL-terminated interface name. - // TODO: add a setsockoptString() - Os.setsockoptIfreq(socket, SOL_SOCKET, SO_BINDTODEVICE, iface); - NetworkUtils.protectFromVpn(socket); - } - - /** - * Make a socket address to communicate with netlink. - */ - @NonNull - public static SocketAddress makeNetlinkSocketAddress(int portId, int groupsMask) { - return new NetlinkSocketAddress(portId, groupsMask); - } - - /** - * Make socket address that packet sockets can bind to. - * - * @param protocol the layer 2 protocol of the packets to receive. One of the {@code ETH_P_*} - * constants in {@link android.system.OsConstants}. - * @param ifIndex the interface index on which packets will be received. - */ - @NonNull - public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex) { - return new PacketSocketAddress( - protocol /* sll_protocol */, - ifIndex /* sll_ifindex */, - null /* sll_addr */); - } - - /** - * Make a socket address that packet socket can send packets to. - * @deprecated Use {@link #makePacketSocketAddress(int, int, byte[])} instead. - * - * @param ifIndex the interface index on which packets will be sent. - * @param hwAddr the hardware address to which packets will be sent. - */ - @Deprecated - @NonNull - public static SocketAddress makePacketSocketAddress(int ifIndex, @NonNull byte[] hwAddr) { - return new PacketSocketAddress( - 0 /* sll_protocol */, - ifIndex /* sll_ifindex */, - hwAddr /* sll_addr */); - } - - /** - * Make a socket address that a packet socket can send packets to. - * - * @param protocol the layer 2 protocol of the packets to send. One of the {@code ETH_P_*} - * constants in {@link android.system.OsConstants}. - * @param ifIndex the interface index on which packets will be sent. - * @param hwAddr the hardware address to which packets will be sent. - */ - @NonNull - public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex, - @NonNull byte[] hwAddr) { - return new PacketSocketAddress( - protocol /* sll_protocol */, - ifIndex /* sll_ifindex */, - hwAddr /* sll_addr */); - } - - /** - * @see IoBridge#closeAndSignalBlockedThreads(FileDescriptor) - */ - public static void closeSocket(@Nullable FileDescriptor fd) throws IOException { - IoBridge.closeAndSignalBlockedThreads(fd); - } - - private SocketUtils() {} -} |
