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:
parent
66ea68e472
commit
fbbccbce69
74 changed files with 23015 additions and 0 deletions
171
framework/src/android/net/CaptivePortal.java
Normal file
171
framework/src/android/net/CaptivePortal.java
Normal 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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
19
framework/src/android/net/CaptivePortalData.aidl
Normal file
19
framework/src/android/net/CaptivePortalData.aidl
Normal 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;
|
||||
305
framework/src/android/net/CaptivePortalData.java
Normal file
305
framework/src/android/net/CaptivePortalData.java
Normal 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
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
20
framework/src/android/net/ConnectionInfo.aidl
Normal file
20
framework/src/android/net/ConnectionInfo.aidl
Normal 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;
|
||||
83
framework/src/android/net/ConnectionInfo.java
Normal file
83
framework/src/android/net/ConnectionInfo.java
Normal 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
777
framework/src/android/net/ConnectivityDiagnosticsManager.java
Normal file
777
framework/src/android/net/ConnectivityDiagnosticsManager.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
5058
framework/src/android/net/ConnectivityManager.java
Normal file
5058
framework/src/android/net/ConnectivityManager.java
Normal file
File diff suppressed because it is too large
Load diff
20
framework/src/android/net/ConnectivityMetricsEvent.aidl
Normal file
20
framework/src/android/net/ConnectivityMetricsEvent.aidl
Normal 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;
|
||||
56
framework/src/android/net/ConnectivityThread.java
Normal file
56
framework/src/android/net/ConnectivityThread.java
Normal 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();
|
||||
}
|
||||
}
|
||||
19
framework/src/android/net/DhcpInfo.aidl
Normal file
19
framework/src/android/net/DhcpInfo.aidl
Normal 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;
|
||||
105
framework/src/android/net/DhcpInfo.java
Normal file
105
framework/src/android/net/DhcpInfo.java
Normal 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
577
framework/src/android/net/DnsResolver.java
Normal file
577
framework/src/android/net/DnsResolver.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
27
framework/src/android/net/ICaptivePortal.aidl
Normal file
27
framework/src/android/net/ICaptivePortal.aidl
Normal 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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
246
framework/src/android/net/IConnectivityManager.aidl
Normal file
246
framework/src/android/net/IConnectivityManager.aidl
Normal 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);
|
||||
}
|
||||
34
framework/src/android/net/ISocketKeepaliveCallback.aidl
Normal file
34
framework/src/android/net/ISocketKeepaliveCallback.aidl
Normal 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();
|
||||
}
|
||||
39
framework/src/android/net/ITestNetworkManager.aidl
Normal file
39
framework/src/android/net/ITestNetworkManager.aidl
Normal 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);
|
||||
}
|
||||
65
framework/src/android/net/InetAddresses.java
Normal file
65
framework/src/android/net/InetAddresses.java
Normal 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);
|
||||
}
|
||||
}
|
||||
19
framework/src/android/net/InterfaceConfiguration.aidl
Normal file
19
framework/src/android/net/InterfaceConfiguration.aidl
Normal 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
Loading…
Reference in a new issue