Snap for 6157842 from 9a294d249cd4c27d8321556eef546933597fc5b9 to rvc-release
Change-Id: I3250d8d05fe3ccf9aa9409883a26a11679604ae0
This commit is contained in:
@@ -18,10 +18,18 @@ package android.net;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.PersistableBundle;
|
||||
|
||||
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.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
@@ -47,38 +55,47 @@ import java.util.concurrent.Executor;
|
||||
* </ul>
|
||||
*/
|
||||
public class ConnectivityDiagnosticsManager {
|
||||
public static final int DETECTION_METHOD_DNS_EVENTS = 1;
|
||||
public static final int DETECTION_METHOD_TCP_METRICS = 2;
|
||||
private final Context mContext;
|
||||
private final IConnectivityManager mService;
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(
|
||||
prefix = {"DETECTION_METHOD_"},
|
||||
value = {DETECTION_METHOD_DNS_EVENTS, DETECTION_METHOD_TCP_METRICS})
|
||||
public @interface DetectionMethod {}
|
||||
public ConnectivityDiagnosticsManager(Context context, IConnectivityManager service) {
|
||||
mContext = Preconditions.checkNotNull(context, "missing context");
|
||||
mService = Preconditions.checkNotNull(service, "missing IConnectivityManager");
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public ConnectivityDiagnosticsManager() {}
|
||||
@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 class ConnectivityReport {
|
||||
public static final class ConnectivityReport implements Parcelable {
|
||||
/** The Network for which this ConnectivityReport applied */
|
||||
@NonNull public final Network network;
|
||||
@NonNull private final Network mNetwork;
|
||||
|
||||
/**
|
||||
* The timestamp for the report. The timestamp is taken from {@link
|
||||
* System#currentTimeMillis}.
|
||||
*/
|
||||
public final long reportTimestamp;
|
||||
private final long mReportTimestamp;
|
||||
|
||||
/** LinkProperties available on the Network at the reported timestamp */
|
||||
@NonNull public final LinkProperties linkProperties;
|
||||
@NonNull private final LinkProperties mLinkProperties;
|
||||
|
||||
/** NetworkCapabilities available on the Network at the reported timestamp */
|
||||
@NonNull public final NetworkCapabilities networkCapabilities;
|
||||
@NonNull private final NetworkCapabilities mNetworkCapabilities;
|
||||
|
||||
/** PersistableBundle that may contain additional info about the report */
|
||||
@NonNull public final PersistableBundle additionalInfo;
|
||||
@NonNull private final PersistableBundle mAdditionalInfo;
|
||||
|
||||
/**
|
||||
* Constructor for ConnectivityReport.
|
||||
@@ -101,30 +118,148 @@ public class ConnectivityDiagnosticsManager {
|
||||
@NonNull LinkProperties linkProperties,
|
||||
@NonNull NetworkCapabilities networkCapabilities,
|
||||
@NonNull PersistableBundle additionalInfo) {
|
||||
this.network = network;
|
||||
this.reportTimestamp = reportTimestamp;
|
||||
this.linkProperties = linkProperties;
|
||||
this.networkCapabilities = networkCapabilities;
|
||||
this.additionalInfo = additionalInfo;
|
||||
mNetwork = network;
|
||||
mReportTimestamp = reportTimestamp;
|
||||
mLinkProperties = linkProperties;
|
||||
mNetworkCapabilities = 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<>() {
|
||||
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 class DataStallReport {
|
||||
public static final class DataStallReport implements Parcelable {
|
||||
public static final int DETECTION_METHOD_DNS_EVENTS = 1;
|
||||
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 {}
|
||||
|
||||
/** The Network for which this DataStallReport applied */
|
||||
@NonNull public final Network network;
|
||||
@NonNull private final Network mNetwork;
|
||||
|
||||
/**
|
||||
* The timestamp for the report. The timestamp is taken from {@link
|
||||
* System#currentTimeMillis}.
|
||||
*/
|
||||
public final long reportTimestamp;
|
||||
private long mReportTimestamp;
|
||||
|
||||
/** The detection method used to identify the suspected data stall */
|
||||
@DetectionMethod public final int detectionMethod;
|
||||
@DetectionMethod private final int mDetectionMethod;
|
||||
|
||||
/** PersistableBundle that may contain additional information on the suspected data stall */
|
||||
@NonNull public final PersistableBundle stallDetails;
|
||||
@NonNull private final PersistableBundle mStallDetails;
|
||||
|
||||
/**
|
||||
* Constructor for DataStallReport.
|
||||
@@ -143,11 +278,101 @@ public class ConnectivityDiagnosticsManager {
|
||||
long reportTimestamp,
|
||||
@DetectionMethod int detectionMethod,
|
||||
@NonNull PersistableBundle stallDetails) {
|
||||
this.network = network;
|
||||
this.reportTimestamp = reportTimestamp;
|
||||
this.detectionMethod = detectionMethod;
|
||||
this.stallDetails = stallDetails;
|
||||
mNetwork = network;
|
||||
mReportTimestamp = reportTimestamp;
|
||||
mDetectionMethod = detectionMethod;
|
||||
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 detection method used to identify this suspected data stall.
|
||||
*
|
||||
* @return The detection method used to identify the suspected data stall
|
||||
*/
|
||||
public int getDetectionMethod() {
|
||||
return mDetectionMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a PersistableBundle with additional info for this report.
|
||||
*
|
||||
* @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)
|
||||
&& persistableBundleEquals(mStallDetails, that.mStallDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mNetwork, mReportTimestamp, mDetectionMethod, 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(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));
|
||||
}
|
||||
|
||||
public DataStallReport[] newArray(int size) {
|
||||
return new DataStallReport[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.IpSecManager.UdpEncapsulationSocket;
|
||||
import android.net.SocketKeepalive.Callback;
|
||||
import android.net.TetheringManager.TetheringEventCallback;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
@@ -58,6 +59,7 @@ import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.internal.util.Protocol;
|
||||
|
||||
@@ -75,6 +77,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@@ -484,34 +487,35 @@ public class ConnectivityManager {
|
||||
* enable if any.
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_ADD_TETHER_TYPE = TetheringManager.EXTRA_ADD_TETHER_TYPE;
|
||||
public static final String EXTRA_ADD_TETHER_TYPE = TetheringConstants.EXTRA_ADD_TETHER_TYPE;
|
||||
|
||||
/**
|
||||
* Extra used for communicating with the TetherService. Includes the type of tethering for
|
||||
* which to cancel provisioning.
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_REM_TETHER_TYPE = TetheringManager.EXTRA_REM_TETHER_TYPE;
|
||||
public static final String EXTRA_REM_TETHER_TYPE = TetheringConstants.EXTRA_REM_TETHER_TYPE;
|
||||
|
||||
/**
|
||||
* Extra used for communicating with the TetherService. True to schedule a recheck of tether
|
||||
* provisioning.
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_SET_ALARM = TetheringManager.EXTRA_SET_ALARM;
|
||||
public static final String EXTRA_SET_ALARM = TetheringConstants.EXTRA_SET_ALARM;
|
||||
|
||||
/**
|
||||
* Tells the TetherService to run a provision check now.
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_RUN_PROVISION = TetheringManager.EXTRA_RUN_PROVISION;
|
||||
public static final String EXTRA_RUN_PROVISION = TetheringConstants.EXTRA_RUN_PROVISION;
|
||||
|
||||
/**
|
||||
* Extra used for communicating with the TetherService. Contains the {@link ResultReceiver}
|
||||
* which will receive provisioning results. Can be left empty.
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_PROVISION_CALLBACK = TetheringManager.EXTRA_PROVISION_CALLBACK;
|
||||
public static final String EXTRA_PROVISION_CALLBACK =
|
||||
TetheringConstants.EXTRA_PROVISION_CALLBACK;
|
||||
|
||||
/**
|
||||
* The absence of a connection type.
|
||||
@@ -2368,10 +2372,12 @@ public class ConnectivityManager {
|
||||
*
|
||||
* @return an array of 0 or more Strings of tetherable interface names.
|
||||
*
|
||||
* @deprecated Use {@link TetheringEventCallback#onTetherableInterfacesChanged(List)} instead.
|
||||
* {@hide}
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
@Deprecated
|
||||
public String[] getTetherableIfaces() {
|
||||
return getTetheringManager().getTetherableIfaces();
|
||||
}
|
||||
@@ -2381,10 +2387,12 @@ public class ConnectivityManager {
|
||||
*
|
||||
* @return an array of 0 or more String of currently tethered interface names.
|
||||
*
|
||||
* @deprecated Use {@link TetheringEventCallback#onTetherableInterfacesChanged(List)} instead.
|
||||
* {@hide}
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
@Deprecated
|
||||
public String[] getTetheredIfaces() {
|
||||
return getTetheringManager().getTetheredIfaces();
|
||||
}
|
||||
@@ -2400,10 +2408,12 @@ public class ConnectivityManager {
|
||||
* @return an array of 0 or more String indicating the interface names
|
||||
* which failed to tether.
|
||||
*
|
||||
* @deprecated Use {@link TetheringEventCallback#onError(String, int)} instead.
|
||||
* {@hide}
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
@Deprecated
|
||||
public String[] getTetheringErroredIfaces() {
|
||||
return getTetheringManager().getTetheringErroredIfaces();
|
||||
}
|
||||
@@ -2412,9 +2422,11 @@ public class ConnectivityManager {
|
||||
* Get the set of tethered dhcp ranges.
|
||||
*
|
||||
* @return an array of 0 or more {@code String} of tethered dhcp ranges.
|
||||
* @deprecated This API just return the default value which is not used in DhcpServer.
|
||||
* {@hide}
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
|
||||
@Deprecated
|
||||
public String[] getTetheredDhcpRanges() {
|
||||
return getTetheringManager().getTetheredDhcpRanges();
|
||||
}
|
||||
@@ -2467,6 +2479,7 @@ public class ConnectivityManager {
|
||||
* {@hide}
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@Deprecated
|
||||
public int untether(String iface) {
|
||||
return getTetheringManager().untether(iface);
|
||||
}
|
||||
@@ -2487,6 +2500,7 @@ public class ConnectivityManager {
|
||||
*
|
||||
* @return a boolean - {@code true} indicating Tethering is supported.
|
||||
*
|
||||
* @deprecated Use {@link TetheringEventCallback#onTetheringSupported(boolean)} instead.
|
||||
* {@hide}
|
||||
*/
|
||||
@SystemApi
|
||||
@@ -2573,9 +2587,12 @@ public class ConnectivityManager {
|
||||
* {@link ConnectivityManager.TETHERING_WIFI},
|
||||
* {@link ConnectivityManager.TETHERING_USB}, or
|
||||
* {@link ConnectivityManager.TETHERING_BLUETOOTH}.
|
||||
*
|
||||
* @deprecated Use {@link TetheringManager#stopTethering} instead.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@Deprecated
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
public void stopTethering(int type) {
|
||||
getTetheringManager().stopTethering(type);
|
||||
@@ -2585,9 +2602,11 @@ public class ConnectivityManager {
|
||||
* Callback for use with {@link registerTetheringEventCallback} to find out tethering
|
||||
* upstream status.
|
||||
*
|
||||
*@hide
|
||||
* @deprecated Use {@line TetheringManager#OnTetheringEventCallback} instead.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@Deprecated
|
||||
public abstract static class OnTetheringEventCallback {
|
||||
|
||||
/**
|
||||
@@ -2600,6 +2619,10 @@ public class ConnectivityManager {
|
||||
public void onUpstreamChanged(@Nullable Network network) {}
|
||||
}
|
||||
|
||||
@GuardedBy("mTetheringEventCallbacks")
|
||||
private final ArrayMap<OnTetheringEventCallback, TetheringEventCallback>
|
||||
mTetheringEventCallbacks = new ArrayMap<>();
|
||||
|
||||
/**
|
||||
* Start listening to tethering change events. Any new added callback will receive the last
|
||||
* tethering status right away. If callback is registered when tethering has no upstream or
|
||||
@@ -2608,16 +2631,30 @@ public class ConnectivityManager {
|
||||
*
|
||||
* @param executor the executor on which callback will be invoked.
|
||||
* @param callback the callback to be called when tethering has change events.
|
||||
*
|
||||
* @deprecated Use {@line TetheringManager#registerTetheringEventCallback} instead.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@Deprecated
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
public void registerTetheringEventCallback(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull final OnTetheringEventCallback callback) {
|
||||
Preconditions.checkNotNull(callback, "OnTetheringEventCallback cannot be null.");
|
||||
|
||||
getTetheringManager().registerTetheringEventCallback(executor, callback);
|
||||
final TetheringEventCallback tetherCallback =
|
||||
new TetheringEventCallback() {
|
||||
@Override
|
||||
public void onUpstreamChanged(@Nullable Network network) {
|
||||
callback.onUpstreamChanged(network);
|
||||
}
|
||||
};
|
||||
|
||||
synchronized (mTetheringEventCallbacks) {
|
||||
mTetheringEventCallbacks.put(callback, tetherCallback);
|
||||
getTetheringManager().registerTetheringEventCallback(executor, tetherCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2625,13 +2662,21 @@ public class ConnectivityManager {
|
||||
* {@link #registerTetheringEventCallback}.
|
||||
*
|
||||
* @param callback previously registered callback.
|
||||
*
|
||||
* @deprecated Use {@link TetheringManager#unregisterTetheringEventCallback} instead.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@Deprecated
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
public void unregisterTetheringEventCallback(
|
||||
@NonNull final OnTetheringEventCallback callback) {
|
||||
getTetheringManager().unregisterTetheringEventCallback(callback);
|
||||
Objects.requireNonNull(callback, "The callback must be non-null");
|
||||
synchronized (mTetheringEventCallbacks) {
|
||||
final TetheringEventCallback tetherCallback =
|
||||
mTetheringEventCallbacks.remove(callback);
|
||||
getTetheringManager().unregisterTetheringEventCallback(tetherCallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2643,10 +2688,12 @@ public class ConnectivityManager {
|
||||
* @return an array of 0 or more regular expression Strings defining
|
||||
* what interfaces are considered tetherable usb interfaces.
|
||||
*
|
||||
* @deprecated Use {@link TetheringEventCallback#onTetherableInterfaceRegexpsChanged} instead.
|
||||
* {@hide}
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
@Deprecated
|
||||
public String[] getTetherableUsbRegexs() {
|
||||
return getTetheringManager().getTetherableUsbRegexs();
|
||||
}
|
||||
@@ -2659,10 +2706,12 @@ public class ConnectivityManager {
|
||||
* @return an array of 0 or more regular expression Strings defining
|
||||
* what interfaces are considered tetherable wifi interfaces.
|
||||
*
|
||||
* @deprecated Use {@link TetheringEventCallback#onTetherableInterfaceRegexpsChanged} instead.
|
||||
* {@hide}
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
@Deprecated
|
||||
public String[] getTetherableWifiRegexs() {
|
||||
return getTetheringManager().getTetherableWifiRegexs();
|
||||
}
|
||||
@@ -2675,10 +2724,13 @@ public class ConnectivityManager {
|
||||
* @return an array of 0 or more regular expression Strings defining
|
||||
* what interfaces are considered tetherable bluetooth interfaces.
|
||||
*
|
||||
* @deprecated Use {@link TetheringEventCallback#onTetherableInterfaceRegexpsChanged(
|
||||
*TetheringManager.TetheringInterfaceRegexps)} instead.
|
||||
* {@hide}
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
@Deprecated
|
||||
public String[] getTetherableBluetoothRegexs() {
|
||||
return getTetheringManager().getTetherableBluetoothRegexs();
|
||||
}
|
||||
@@ -2705,37 +2757,104 @@ public class ConnectivityManager {
|
||||
return getTetheringManager().setUsbTethering(enable);
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_NO_ERROR}.
|
||||
* {@hide}
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int TETHER_ERROR_NO_ERROR = 0;
|
||||
/** {@hide} */
|
||||
public static final int TETHER_ERROR_UNKNOWN_IFACE = 1;
|
||||
/** {@hide} */
|
||||
public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2;
|
||||
/** {@hide} */
|
||||
public static final int TETHER_ERROR_UNSUPPORTED = 3;
|
||||
/** {@hide} */
|
||||
public static final int TETHER_ERROR_UNAVAIL_IFACE = 4;
|
||||
/** {@hide} */
|
||||
public static final int TETHER_ERROR_MASTER_ERROR = 5;
|
||||
/** {@hide} */
|
||||
public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
|
||||
/** {@hide} */
|
||||
public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
|
||||
/** {@hide} */
|
||||
public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8;
|
||||
/** {@hide} */
|
||||
public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9;
|
||||
/** {@hide} */
|
||||
public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10;
|
||||
/** {@hide} */
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_NO_ERROR = TetheringManager.TETHER_ERROR_NO_ERROR;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_UNKNOWN_IFACE}.
|
||||
* {@hide}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_UNKNOWN_IFACE =
|
||||
TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_SERVICE_UNAVAIL}.
|
||||
* {@hide}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_SERVICE_UNAVAIL =
|
||||
TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_UNSUPPORTED}.
|
||||
* {@hide}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_UNSUPPORTED = TetheringManager.TETHER_ERROR_UNSUPPORTED;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_UNAVAIL_IFACE}.
|
||||
* {@hide}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_UNAVAIL_IFACE =
|
||||
TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_MASTER_ERROR}.
|
||||
* {@hide}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_MASTER_ERROR = TetheringManager.TETHER_ERROR_MASTER_ERROR;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_TETHER_IFACE_ERROR}.
|
||||
* {@hide}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_TETHER_IFACE_ERROR =
|
||||
TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_UNTETHER_IFACE_ERROR}.
|
||||
* {@hide}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR =
|
||||
TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_ENABLE_NAT_ERROR}.
|
||||
* {@hide}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_ENABLE_NAT_ERROR =
|
||||
TetheringManager.TETHER_ERROR_ENABLE_NAT_ERROR;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_DISABLE_NAT_ERROR}.
|
||||
* {@hide}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_DISABLE_NAT_ERROR =
|
||||
TetheringManager.TETHER_ERROR_DISABLE_NAT_ERROR;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_IFACE_CFG_ERROR}.
|
||||
* {@hide}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_IFACE_CFG_ERROR =
|
||||
TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_PROVISION_FAILED}.
|
||||
* {@hide}
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int TETHER_ERROR_PROVISION_FAILED = 11;
|
||||
/** {@hide} */
|
||||
public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12;
|
||||
/** {@hide} */
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_PROVISION_FAILED =
|
||||
TetheringManager.TETHER_ERROR_PROVISION_FAILED;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_DHCPSERVER_ERROR}.
|
||||
* {@hide}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_DHCPSERVER_ERROR =
|
||||
TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR;
|
||||
/**
|
||||
* @deprecated Use {@link TetheringManager#TETHER_ERROR_ENTITLEMENT_UNKNOWN}.
|
||||
* {@hide}
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN = 13;
|
||||
@Deprecated
|
||||
public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN =
|
||||
TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
|
||||
|
||||
/**
|
||||
* Get a more detailed error code after a Tethering or Untethering
|
||||
@@ -2745,10 +2864,12 @@ public class ConnectivityManager {
|
||||
* @return error The error code of the last error tethering or untethering the named
|
||||
* interface
|
||||
*
|
||||
* @deprecated Use {@link TetheringEventCallback#onError(String, int)} instead.
|
||||
* {@hide}
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
@Deprecated
|
||||
public int getLastTetherError(String iface) {
|
||||
return getTetheringManager().getLastTetherError(iface);
|
||||
}
|
||||
@@ -2766,9 +2887,12 @@ public class ConnectivityManager {
|
||||
/**
|
||||
* Callback for use with {@link #getLatestTetheringEntitlementResult} to find out whether
|
||||
* entitlement succeeded.
|
||||
*
|
||||
* @deprecated Use {@link TetheringManager#OnTetheringEntitlementResultListener} instead.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@Deprecated
|
||||
public interface OnTetheringEntitlementResultListener {
|
||||
/**
|
||||
* Called to notify entitlement result.
|
||||
@@ -2798,9 +2922,11 @@ public class ConnectivityManager {
|
||||
* @param listener an {@link OnTetheringEntitlementResultListener} which will be called to
|
||||
* notify the caller of the result of entitlement check. The listener may be called zero
|
||||
* or one time.
|
||||
* @deprecated Use {@link TetheringManager#requestLatestTetheringEntitlementResult} instead.
|
||||
* {@hide}
|
||||
*/
|
||||
@SystemApi
|
||||
@Deprecated
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
public void getLatestTetheringEntitlementResult(int type, boolean showEntitlementUi,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.net;
|
||||
import static android.system.OsConstants.IFA_F_DADFAILED;
|
||||
import static android.system.OsConstants.IFA_F_DEPRECATED;
|
||||
import static android.system.OsConstants.IFA_F_OPTIMISTIC;
|
||||
import static android.system.OsConstants.IFA_F_PERMANENT;
|
||||
import static android.system.OsConstants.IFA_F_TENTATIVE;
|
||||
import static android.system.OsConstants.RT_SCOPE_HOST;
|
||||
import static android.system.OsConstants.RT_SCOPE_LINK;
|
||||
@@ -34,6 +35,7 @@ import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.os.Build;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Pair;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
@@ -41,6 +43,7 @@ import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InterfaceAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Identifies an IP address on a network link.
|
||||
@@ -58,6 +61,21 @@ import java.net.UnknownHostException;
|
||||
* </ul>
|
||||
*/
|
||||
public class LinkAddress implements Parcelable {
|
||||
|
||||
/**
|
||||
* Indicates the deprecation or expiration time is unknown
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final long LIFETIME_UNKNOWN = -1;
|
||||
|
||||
/**
|
||||
* Indicates this address is permanent.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final long LIFETIME_PERMANENT = Long.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* IPv4 or IPv6 address.
|
||||
*/
|
||||
@@ -71,7 +89,9 @@ public class LinkAddress implements Parcelable {
|
||||
private int prefixLength;
|
||||
|
||||
/**
|
||||
* Address flags. A bitmask of IFA_F_* values.
|
||||
* Address flags. A bitmask of {@code IFA_F_*} values. Note that {@link #getFlags()} may not
|
||||
* return these exact values. For example, it may set or clear the {@code IFA_F_DEPRECATED}
|
||||
* flag depending on the current preferred lifetime.
|
||||
*/
|
||||
private int flags;
|
||||
|
||||
@@ -80,6 +100,23 @@ public class LinkAddress implements Parcelable {
|
||||
*/
|
||||
private int scope;
|
||||
|
||||
/**
|
||||
* The time, as reported by {@link SystemClock#elapsedRealtime}, when this LinkAddress will be
|
||||
* or was deprecated. {@link #LIFETIME_UNKNOWN} indicates this information is not available. At
|
||||
* the time existing connections can still use this address until it expires, but new
|
||||
* connections should use the new address. {@link #LIFETIME_PERMANENT} indicates this
|
||||
* {@link LinkAddress} will never be deprecated.
|
||||
*/
|
||||
private long deprecationTime;
|
||||
|
||||
/**
|
||||
* The time, as reported by {@link SystemClock#elapsedRealtime}, when this {@link LinkAddress}
|
||||
* will expire and be removed from the interface. {@link #LIFETIME_UNKNOWN} indicates this
|
||||
* information is not available. {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress}
|
||||
* will never expire.
|
||||
*/
|
||||
private long expirationTime;
|
||||
|
||||
/**
|
||||
* Utility function to determines the scope of a unicast address. Per RFC 4291 section 2.5 and
|
||||
* RFC 6724 section 3.2.
|
||||
@@ -152,7 +189,8 @@ public class LinkAddress implements Parcelable {
|
||||
/**
|
||||
* Utility function for the constructors.
|
||||
*/
|
||||
private void init(InetAddress address, int prefixLength, int flags, int scope) {
|
||||
private void init(InetAddress address, int prefixLength, int flags, int scope,
|
||||
long deprecationTime, long expirationTime) {
|
||||
if (address == null ||
|
||||
address.isMulticastAddress() ||
|
||||
prefixLength < 0 ||
|
||||
@@ -161,15 +199,42 @@ public class LinkAddress implements Parcelable {
|
||||
throw new IllegalArgumentException("Bad LinkAddress params " + address +
|
||||
"/" + prefixLength);
|
||||
}
|
||||
|
||||
// deprecation time and expiration time must be both provided, or neither.
|
||||
if ((deprecationTime == LIFETIME_UNKNOWN) != (expirationTime == LIFETIME_UNKNOWN)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Must not specify only one of deprecation time and expiration time");
|
||||
}
|
||||
|
||||
// deprecation time needs to be a positive value.
|
||||
if (deprecationTime != LIFETIME_UNKNOWN && deprecationTime < 0) {
|
||||
throw new IllegalArgumentException("invalid deprecation time " + deprecationTime);
|
||||
}
|
||||
|
||||
// expiration time needs to be a positive value.
|
||||
if (expirationTime != LIFETIME_UNKNOWN && expirationTime < 0) {
|
||||
throw new IllegalArgumentException("invalid expiration time " + expirationTime);
|
||||
}
|
||||
|
||||
// expiration time can't be earlier than deprecation time
|
||||
if (deprecationTime != LIFETIME_UNKNOWN && expirationTime != LIFETIME_UNKNOWN
|
||||
&& expirationTime < deprecationTime) {
|
||||
throw new IllegalArgumentException("expiration earlier than deprecation ("
|
||||
+ deprecationTime + ", " + expirationTime + ")");
|
||||
}
|
||||
|
||||
this.address = address;
|
||||
this.prefixLength = prefixLength;
|
||||
this.flags = flags;
|
||||
this.scope = scope;
|
||||
this.deprecationTime = deprecationTime;
|
||||
this.expirationTime = expirationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LinkAddress} from an {@code InetAddress} and prefix length, with
|
||||
* the specified flags and scope. Flags and scope are not checked for validity.
|
||||
*
|
||||
* @param address The IP address.
|
||||
* @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
|
||||
* @param flags A bitmask of {@code IFA_F_*} values representing properties of the address.
|
||||
@@ -181,7 +246,39 @@ public class LinkAddress implements Parcelable {
|
||||
@TestApi
|
||||
public LinkAddress(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength,
|
||||
int flags, int scope) {
|
||||
init(address, prefixLength, flags, scope);
|
||||
init(address, prefixLength, flags, scope, LIFETIME_UNKNOWN, LIFETIME_UNKNOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LinkAddress} from an {@code InetAddress}, prefix length, with
|
||||
* the specified flags, scope, deprecation time, and expiration time. Flags and scope are not
|
||||
* checked for validity. The value of the {@code IFA_F_DEPRECATED} and {@code IFA_F_PERMANENT}
|
||||
* flag will be adjusted based on the passed-in lifetimes.
|
||||
*
|
||||
* @param address The IP address.
|
||||
* @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
|
||||
* @param flags A bitmask of {@code IFA_F_*} values representing properties of the address.
|
||||
* @param scope An integer defining the scope in which the address is unique (e.g.,
|
||||
* {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}).
|
||||
* @param deprecationTime The time, as reported by {@link SystemClock#elapsedRealtime}, when
|
||||
* this {@link LinkAddress} will be or was deprecated.
|
||||
* {@link #LIFETIME_UNKNOWN} indicates this information is not available.
|
||||
* At the time existing connections can still use this address until it
|
||||
* expires, but new connections should use the new address.
|
||||
* {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress} will
|
||||
* never be deprecated.
|
||||
* @param expirationTime The time, as reported by {@link SystemClock#elapsedRealtime}, when this
|
||||
* {@link LinkAddress} will expire and be removed from the interface.
|
||||
* {@link #LIFETIME_UNKNOWN} indicates this information is not available.
|
||||
* {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress} will
|
||||
* never expire.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public LinkAddress(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength,
|
||||
int flags, int scope, long deprecationTime, long expirationTime) {
|
||||
init(address, prefixLength, flags, scope, deprecationTime, expirationTime);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,7 +334,7 @@ public class LinkAddress implements Parcelable {
|
||||
// This may throw an IllegalArgumentException; catching it is the caller's responsibility.
|
||||
// TODO: consider rejecting mapped IPv4 addresses such as "::ffff:192.0.2.5/24".
|
||||
Pair<InetAddress, Integer> ipAndMask = NetworkUtils.parseIpAndMask(address);
|
||||
init(ipAndMask.first, ipAndMask.second, flags, scope);
|
||||
init(ipAndMask.first, ipAndMask.second, flags, scope, LIFETIME_UNKNOWN, LIFETIME_UNKNOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,10 +362,12 @@ public class LinkAddress implements Parcelable {
|
||||
return false;
|
||||
}
|
||||
LinkAddress linkAddress = (LinkAddress) obj;
|
||||
return this.address.equals(linkAddress.address) &&
|
||||
this.prefixLength == linkAddress.prefixLength &&
|
||||
this.flags == linkAddress.flags &&
|
||||
this.scope == linkAddress.scope;
|
||||
return this.address.equals(linkAddress.address)
|
||||
&& this.prefixLength == linkAddress.prefixLength
|
||||
&& this.flags == linkAddress.flags
|
||||
&& this.scope == linkAddress.scope
|
||||
&& this.deprecationTime == linkAddress.deprecationTime
|
||||
&& this.expirationTime == linkAddress.expirationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,7 +375,7 @@ public class LinkAddress implements Parcelable {
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return address.hashCode() + 11 * prefixLength + 19 * flags + 43 * scope;
|
||||
return Objects.hash(address, prefixLength, flags, scope, deprecationTime, expirationTime);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -329,6 +428,25 @@ public class LinkAddress implements Parcelable {
|
||||
* Returns the flags of this {@code LinkAddress}.
|
||||
*/
|
||||
public int getFlags() {
|
||||
int flags = this.flags;
|
||||
if (deprecationTime != LIFETIME_UNKNOWN) {
|
||||
if (SystemClock.elapsedRealtime() >= deprecationTime) {
|
||||
flags |= IFA_F_DEPRECATED;
|
||||
} else {
|
||||
// If deprecation time is in the future, or permanent.
|
||||
flags &= ~IFA_F_DEPRECATED;
|
||||
}
|
||||
}
|
||||
|
||||
if (expirationTime == LIFETIME_PERMANENT) {
|
||||
flags |= IFA_F_PERMANENT;
|
||||
} else if (expirationTime != LIFETIME_UNKNOWN) {
|
||||
// If we know this address expired or will expire in the future or, then this address
|
||||
// should not be permanent.
|
||||
flags &= ~IFA_F_PERMANENT;
|
||||
}
|
||||
|
||||
// Do no touch the original flags. Return the adjusted flags here.
|
||||
return flags;
|
||||
}
|
||||
|
||||
@@ -340,7 +458,35 @@ public class LinkAddress implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this {@code LinkAddress} is global scope and preferred.
|
||||
* @return The time that this address will be deprecated. At the time the existing connection
|
||||
* can still use this address until it expires, but the new connection should use the new
|
||||
* address. This is the EPOCH time in milliseconds. 0 indicates this information is not
|
||||
* available.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public long getDeprecationTime() {
|
||||
return deprecationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The time that this address will expire and will be no longer valid. This is the EPOCH
|
||||
* time in milliseconds. 0 indicates this information is not available.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public long getExpirationTime() {
|
||||
return expirationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this {@code LinkAddress} is global scope and preferred (i.e., not currently
|
||||
* deprecated).
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@@ -352,6 +498,7 @@ public class LinkAddress implements Parcelable {
|
||||
* state has cleared either DAD has succeeded or failed, and both
|
||||
* flags are cleared regardless).
|
||||
*/
|
||||
int flags = getFlags();
|
||||
return (scope == RT_SCOPE_UNIVERSE
|
||||
&& !isIpv6ULA()
|
||||
&& (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED)) == 0L
|
||||
@@ -373,6 +520,8 @@ public class LinkAddress implements Parcelable {
|
||||
dest.writeInt(prefixLength);
|
||||
dest.writeInt(this.flags);
|
||||
dest.writeInt(scope);
|
||||
dest.writeLong(deprecationTime);
|
||||
dest.writeLong(expirationTime);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -392,7 +541,10 @@ public class LinkAddress implements Parcelable {
|
||||
int prefixLength = in.readInt();
|
||||
int flags = in.readInt();
|
||||
int scope = in.readInt();
|
||||
return new LinkAddress(address, prefixLength, flags, scope);
|
||||
long deprecationTime = in.readLong();
|
||||
long expirationTime = in.readLong();
|
||||
return new LinkAddress(address, prefixLength, flags, scope, deprecationTime,
|
||||
expirationTime);
|
||||
}
|
||||
|
||||
public LinkAddress[] newArray(int size) {
|
||||
|
||||
@@ -304,7 +304,10 @@ public abstract class NetworkAgent {
|
||||
private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
|
||||
// The subtype can be changed with (TODO) setLegacySubtype, but it starts
|
||||
// with the type and an empty description.
|
||||
return new NetworkInfo(config.legacyType, config.legacyType, config.legacyTypeName, "");
|
||||
final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacyType,
|
||||
config.legacyTypeName, "");
|
||||
ni.setIsAvailable(true);
|
||||
return ni;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,6 +38,8 @@ import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
@@ -316,11 +318,83 @@ public class LinkAddressTest {
|
||||
|
||||
l = new LinkAddress(V6_ADDRESS, 64, 123, 456);
|
||||
assertParcelingIsLossless(l);
|
||||
l = new LinkAddress(V6_ADDRESS, 64, 123, 456,
|
||||
1L, 3600000L);
|
||||
assertParcelingIsLossless(l);
|
||||
|
||||
l = new LinkAddress(V4 + "/28", IFA_F_PERMANENT, RT_SCOPE_LINK);
|
||||
assertParcelSane(l, 4);
|
||||
assertParcelSane(l, 6);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeprecationTime() {
|
||||
try {
|
||||
new LinkAddress(V6_ADDRESS, 64, 0, 456,
|
||||
LinkAddress.LIFETIME_UNKNOWN,
|
||||
SystemClock.elapsedRealtime() + 200000);
|
||||
fail("Only one time provided should cause exception");
|
||||
} catch (IllegalArgumentException expected) { }
|
||||
|
||||
try {
|
||||
new LinkAddress(V6_ADDRESS, 64, 0, 456,
|
||||
SystemClock.elapsedRealtime() - 100000,
|
||||
SystemClock.elapsedRealtime() - 200000);
|
||||
fail("deprecation time later than expiration time should cause exception");
|
||||
} catch (IllegalArgumentException expected) { }
|
||||
|
||||
try {
|
||||
new LinkAddress(V6_ADDRESS, 64, 0, 456,
|
||||
-2, SystemClock.elapsedRealtime());
|
||||
fail("negative deprecation time should cause exception");
|
||||
} catch (IllegalArgumentException expected) { }
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpirationTime() {
|
||||
try {
|
||||
new LinkAddress(V6_ADDRESS, 64, 0, 456,
|
||||
SystemClock.elapsedRealtime() + 200000,
|
||||
LinkAddress.LIFETIME_UNKNOWN);
|
||||
fail("Only one time provided should cause exception");
|
||||
} catch (IllegalArgumentException expected) { }
|
||||
|
||||
try {
|
||||
new LinkAddress(V6_ADDRESS, 64, 0, 456,
|
||||
SystemClock.elapsedRealtime() - 10000, -2);
|
||||
fail("negative expiration time should cause exception");
|
||||
} catch (IllegalArgumentException expected) { }
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFlags() {
|
||||
LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 123, RT_SCOPE_HOST);
|
||||
assertEquals(123, l.getFlags());
|
||||
|
||||
// Test if deprecated bit was added/remove automatically based on the provided deprecation
|
||||
// time
|
||||
l = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_HOST,
|
||||
SystemClock.elapsedRealtime() - 100000, LinkAddress.LIFETIME_PERMANENT);
|
||||
// Check if the flag is added automatically.
|
||||
assertTrue((l.getFlags() & IFA_F_DEPRECATED) != 0);
|
||||
|
||||
l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, RT_SCOPE_HOST,
|
||||
SystemClock.elapsedRealtime() + 100000, LinkAddress.LIFETIME_PERMANENT);
|
||||
// Check if the flag is removed automatically.
|
||||
assertTrue((l.getFlags() & IFA_F_DEPRECATED) == 0);
|
||||
|
||||
l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, RT_SCOPE_HOST,
|
||||
LinkAddress.LIFETIME_PERMANENT, LinkAddress.LIFETIME_PERMANENT);
|
||||
// Check if the permanent flag is added.
|
||||
assertTrue((l.getFlags() & IFA_F_PERMANENT) != 0);
|
||||
|
||||
l = new LinkAddress(V6_ADDRESS, 64, IFA_F_PERMANENT, RT_SCOPE_HOST,
|
||||
SystemClock.elapsedRealtime() - 100000,
|
||||
SystemClock.elapsedRealtime() + 100000);
|
||||
// Check if the permanent flag is removed
|
||||
assertTrue((l.getFlags() & IFA_F_PERMANENT) == 0);
|
||||
}
|
||||
|
||||
|
||||
private void assertGlobalPreferred(LinkAddress l, String msg) {
|
||||
assertTrue(msg, l.isGlobalPreferred());
|
||||
}
|
||||
@@ -389,5 +463,12 @@ public class LinkAddressTest {
|
||||
(IFA_F_TEMPORARY|IFA_F_TENTATIVE|IFA_F_OPTIMISTIC),
|
||||
RT_SCOPE_UNIVERSE);
|
||||
assertGlobalPreferred(l, "v6,global,tempaddr+optimistic");
|
||||
|
||||
l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED,
|
||||
RT_SCOPE_UNIVERSE, SystemClock.elapsedRealtime() + 100000,
|
||||
SystemClock.elapsedRealtime() + 200000);
|
||||
// Although the deprecated bit is set, but the deprecation time is in the future, test
|
||||
// if the flag is removed automatically.
|
||||
assertGlobalPreferred(l, "v6,global,tempaddr+deprecated in the future");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
|
||||
import static android.net.ConnectivityDiagnosticsManager.DataStallReport;
|
||||
|
||||
import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.os.PersistableBundle;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class ConnectivityDiagnosticsManagerTest {
|
||||
private static final int NET_ID = 1;
|
||||
private static final int DETECTION_METHOD = 2;
|
||||
private static final long TIMESTAMP = 10L;
|
||||
private static final String INTERFACE_NAME = "interface";
|
||||
private static final String BUNDLE_KEY = "key";
|
||||
private static final String BUNDLE_VALUE = "value";
|
||||
|
||||
private ConnectivityReport createSampleConnectivityReport() {
|
||||
final LinkProperties linkProperties = new LinkProperties();
|
||||
linkProperties.setInterfaceName(INTERFACE_NAME);
|
||||
|
||||
final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
|
||||
networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
|
||||
|
||||
final PersistableBundle bundle = new PersistableBundle();
|
||||
bundle.putString(BUNDLE_KEY, BUNDLE_VALUE);
|
||||
|
||||
return new ConnectivityReport(
|
||||
new Network(NET_ID), TIMESTAMP, linkProperties, networkCapabilities, bundle);
|
||||
}
|
||||
|
||||
private ConnectivityReport createDefaultConnectivityReport() {
|
||||
return new ConnectivityReport(
|
||||
new Network(0),
|
||||
0L,
|
||||
new LinkProperties(),
|
||||
new NetworkCapabilities(),
|
||||
PersistableBundle.EMPTY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistableBundleEquals() {
|
||||
assertFalse(
|
||||
ConnectivityDiagnosticsManager.persistableBundleEquals(
|
||||
null, PersistableBundle.EMPTY));
|
||||
assertFalse(
|
||||
ConnectivityDiagnosticsManager.persistableBundleEquals(
|
||||
PersistableBundle.EMPTY, null));
|
||||
assertTrue(
|
||||
ConnectivityDiagnosticsManager.persistableBundleEquals(
|
||||
PersistableBundle.EMPTY, PersistableBundle.EMPTY));
|
||||
|
||||
final PersistableBundle a = new PersistableBundle();
|
||||
a.putString(BUNDLE_KEY, BUNDLE_VALUE);
|
||||
|
||||
final PersistableBundle b = new PersistableBundle();
|
||||
b.putString(BUNDLE_KEY, BUNDLE_VALUE);
|
||||
|
||||
final PersistableBundle c = new PersistableBundle();
|
||||
c.putString(BUNDLE_KEY, null);
|
||||
|
||||
assertFalse(
|
||||
ConnectivityDiagnosticsManager.persistableBundleEquals(PersistableBundle.EMPTY, a));
|
||||
assertFalse(
|
||||
ConnectivityDiagnosticsManager.persistableBundleEquals(a, PersistableBundle.EMPTY));
|
||||
|
||||
assertTrue(ConnectivityDiagnosticsManager.persistableBundleEquals(a, b));
|
||||
assertTrue(ConnectivityDiagnosticsManager.persistableBundleEquals(b, a));
|
||||
|
||||
assertFalse(ConnectivityDiagnosticsManager.persistableBundleEquals(a, c));
|
||||
assertFalse(ConnectivityDiagnosticsManager.persistableBundleEquals(c, a));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectivityReportEquals() {
|
||||
assertEquals(createSampleConnectivityReport(), createSampleConnectivityReport());
|
||||
assertEquals(createDefaultConnectivityReport(), createDefaultConnectivityReport());
|
||||
|
||||
final LinkProperties linkProperties = new LinkProperties();
|
||||
linkProperties.setInterfaceName(INTERFACE_NAME);
|
||||
|
||||
final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
|
||||
networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
|
||||
|
||||
final PersistableBundle bundle = new PersistableBundle();
|
||||
bundle.putString(BUNDLE_KEY, BUNDLE_VALUE);
|
||||
|
||||
assertNotEquals(
|
||||
createDefaultConnectivityReport(),
|
||||
new ConnectivityReport(
|
||||
new Network(NET_ID),
|
||||
0L,
|
||||
new LinkProperties(),
|
||||
new NetworkCapabilities(),
|
||||
PersistableBundle.EMPTY));
|
||||
assertNotEquals(
|
||||
createDefaultConnectivityReport(),
|
||||
new ConnectivityReport(
|
||||
new Network(0),
|
||||
TIMESTAMP,
|
||||
new LinkProperties(),
|
||||
new NetworkCapabilities(),
|
||||
PersistableBundle.EMPTY));
|
||||
assertNotEquals(
|
||||
createDefaultConnectivityReport(),
|
||||
new ConnectivityReport(
|
||||
new Network(0),
|
||||
0L,
|
||||
linkProperties,
|
||||
new NetworkCapabilities(),
|
||||
PersistableBundle.EMPTY));
|
||||
assertNotEquals(
|
||||
createDefaultConnectivityReport(),
|
||||
new ConnectivityReport(
|
||||
new Network(0),
|
||||
TIMESTAMP,
|
||||
new LinkProperties(),
|
||||
networkCapabilities,
|
||||
PersistableBundle.EMPTY));
|
||||
assertNotEquals(
|
||||
createDefaultConnectivityReport(),
|
||||
new ConnectivityReport(
|
||||
new Network(0),
|
||||
TIMESTAMP,
|
||||
new LinkProperties(),
|
||||
new NetworkCapabilities(),
|
||||
bundle));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectivityReportParcelUnparcel() {
|
||||
assertParcelSane(createSampleConnectivityReport(), 5);
|
||||
}
|
||||
|
||||
private DataStallReport createSampleDataStallReport() {
|
||||
final PersistableBundle bundle = new PersistableBundle();
|
||||
bundle.putString(BUNDLE_KEY, BUNDLE_VALUE);
|
||||
return new DataStallReport(new Network(NET_ID), TIMESTAMP, DETECTION_METHOD, bundle);
|
||||
}
|
||||
|
||||
private DataStallReport createDefaultDataStallReport() {
|
||||
return new DataStallReport(new Network(0), 0L, 0, PersistableBundle.EMPTY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataStallReportEquals() {
|
||||
assertEquals(createSampleDataStallReport(), createSampleDataStallReport());
|
||||
assertEquals(createDefaultDataStallReport(), createDefaultDataStallReport());
|
||||
|
||||
final PersistableBundle bundle = new PersistableBundle();
|
||||
bundle.putString(BUNDLE_KEY, BUNDLE_VALUE);
|
||||
|
||||
assertNotEquals(
|
||||
createDefaultDataStallReport(),
|
||||
new DataStallReport(new Network(NET_ID), 0L, 0, PersistableBundle.EMPTY));
|
||||
assertNotEquals(
|
||||
createDefaultDataStallReport(),
|
||||
new DataStallReport(new Network(0), TIMESTAMP, 0, PersistableBundle.EMPTY));
|
||||
assertNotEquals(
|
||||
createDefaultDataStallReport(),
|
||||
new DataStallReport(new Network(0), 0L, DETECTION_METHOD, PersistableBundle.EMPTY));
|
||||
assertNotEquals(
|
||||
createDefaultDataStallReport(), new DataStallReport(new Network(0), 0L, 0, bundle));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataStallReportParcelUnparcel() {
|
||||
assertParcelSane(createSampleDataStallReport(), 4);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user