Move module sources to packages/Connectivity

Files that are planned to be part of the connectivity module are grouped
in packages/Connectivity, so they can be built separately and moved in
one operation with their history into packages/modules/Connectivity.

This places the files in the existing framework-connectivity-sources
filegroup instead of the current framework-core-sources filegroup. Both
are used the same way in framework-non-updatable-sources.

Bug: 171540887
Test: m
Change-Id: I62d9d91574ace6f5c4624035d190260c3126b91e
This commit is contained in:
Remi NGUYEN VAN 2021-01-15 18:08:24 +09:00
commit fbbccbce69
74 changed files with 23015 additions and 0 deletions

View file

@ -0,0 +1,171 @@
/*
* 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) {
}
}
}

View file

@ -0,0 +1,19 @@
/*
* 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;

View file

@ -0,0 +1,305 @@
/*
* 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
+ "}";
}
}

View file

@ -0,0 +1,20 @@
/*
**
** 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;

View file

@ -0,0 +1,83 @@
/*
* 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];
}
};
}

View file

@ -0,0 +1,21 @@
/**
*
* 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;

View file

@ -0,0 +1,777 @@
/*
* 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();
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,20 @@
/*
* 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;

View file

@ -0,0 +1,56 @@
/*
* 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();
}
}

View file

@ -0,0 +1,19 @@
/**
* 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;

View file

@ -0,0 +1,105 @@
/*
* 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];
}
};
}

View file

@ -0,0 +1,577 @@
/*
* 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;
}
}
}

View file

@ -0,0 +1,27 @@
/**
* 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);
}

View file

@ -0,0 +1,28 @@
/**
*
* 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);
}

View file

@ -0,0 +1,246 @@
/**
* 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);
}

View file

@ -0,0 +1,34 @@
/**
* 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();
}

View file

@ -0,0 +1,39 @@
/**
* 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);
}

View file

@ -0,0 +1,65 @@
/*
* 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);
}
}

View file

@ -0,0 +1,19 @@
/**
* 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;

Some files were not shown because too many files have changed in this diff Show more