Allows the caller to specify configuration by TetheringRequest
This is initial work to allow caller to pass their prefered
configuration to start tethering. Caller may able to specify the
downstream interface ipv4 address with dhcp server disabled for
static IP configuration, or able to exempt entitlement check if
they have permission in follow up CL.
Bug: 141256482
Test: -atest TetheringTest
-ON/OFF wifi tethering
Change-Id: Ic7c3a33195bbd7e72f9b8e73fa148be476b87bf3
Merged-In: Ic7c3a33195bbd7e72f9b8e73fa148be476b87bf3
This commit is contained in:
committed by
Lorenzo Colitti
parent
75b6d7b8ae
commit
0688917e74
@@ -4306,8 +4306,8 @@ package android.net {
|
||||
method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean);
|
||||
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, "android.permission.NETWORK_STACK"}) public boolean shouldAvoidBadWifi();
|
||||
method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
|
||||
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
|
||||
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int);
|
||||
method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void unregisterNetworkProvider(@NonNull android.net.NetworkProvider);
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void unregisterTetheringEventCallback(@NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
|
||||
@@ -4323,10 +4323,10 @@ package android.net {
|
||||
field @Deprecated public static final int TYPE_WIFI_P2P = 13; // 0xd
|
||||
}
|
||||
|
||||
public abstract static class ConnectivityManager.OnStartTetheringCallback {
|
||||
ctor public ConnectivityManager.OnStartTetheringCallback();
|
||||
method public void onTetheringFailed();
|
||||
method public void onTetheringStarted();
|
||||
@Deprecated public abstract static class ConnectivityManager.OnStartTetheringCallback {
|
||||
ctor @Deprecated public ConnectivityManager.OnStartTetheringCallback();
|
||||
method @Deprecated public void onTetheringFailed();
|
||||
method @Deprecated public void onTetheringStarted();
|
||||
}
|
||||
|
||||
@Deprecated public static interface ConnectivityManager.OnTetheringEntitlementResultListener {
|
||||
@@ -4655,11 +4655,13 @@ package android.net {
|
||||
}
|
||||
|
||||
public class TetheringManager {
|
||||
method public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
|
||||
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
|
||||
method public void stopAllTethering();
|
||||
method public void stopTethering(int);
|
||||
method public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
|
||||
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
|
||||
field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED";
|
||||
field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY";
|
||||
field public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
|
||||
@@ -4692,6 +4694,12 @@ package android.net {
|
||||
method public void onTetheringEntitlementResult(int);
|
||||
}
|
||||
|
||||
public abstract static class TetheringManager.StartTetheringCallback {
|
||||
ctor public TetheringManager.StartTetheringCallback();
|
||||
method public void onTetheringFailed(int);
|
||||
method public void onTetheringStarted();
|
||||
}
|
||||
|
||||
public abstract static class TetheringManager.TetheringEventCallback {
|
||||
ctor public TetheringManager.TetheringEventCallback();
|
||||
method public void onError(@NonNull String, int);
|
||||
@@ -4709,6 +4717,17 @@ package android.net {
|
||||
method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
|
||||
}
|
||||
|
||||
public static class TetheringManager.TetheringRequest {
|
||||
}
|
||||
|
||||
public static class TetheringManager.TetheringRequest.Builder {
|
||||
ctor public TetheringManager.TetheringRequest.Builder(int);
|
||||
method @NonNull public android.net.TetheringManager.TetheringRequest build();
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setSilentProvisioning(boolean);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder useStaticIpv4Addresses(@NonNull android.net.LinkAddress);
|
||||
}
|
||||
|
||||
public class TrafficStats {
|
||||
method public static void setThreadStatsTagApp();
|
||||
method public static void setThreadStatsTagBackup();
|
||||
|
||||
@@ -1476,11 +1476,13 @@ package android.net {
|
||||
}
|
||||
|
||||
public class TetheringManager {
|
||||
method public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
|
||||
method @RequiresPermission("android.permission.TETHER_PRIVILEGED") public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
|
||||
method public void stopAllTethering();
|
||||
method public void stopTethering(int);
|
||||
method public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
|
||||
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
|
||||
method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
|
||||
method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
|
||||
method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
|
||||
method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
|
||||
method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
|
||||
method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
|
||||
field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED";
|
||||
field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY";
|
||||
field public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
|
||||
@@ -1513,6 +1515,12 @@ package android.net {
|
||||
method public void onTetheringEntitlementResult(int);
|
||||
}
|
||||
|
||||
public abstract static class TetheringManager.StartTetheringCallback {
|
||||
ctor public TetheringManager.StartTetheringCallback();
|
||||
method public void onTetheringFailed(int);
|
||||
method public void onTetheringStarted();
|
||||
}
|
||||
|
||||
public abstract static class TetheringManager.TetheringEventCallback {
|
||||
ctor public TetheringManager.TetheringEventCallback();
|
||||
method public void onError(@NonNull String, int);
|
||||
@@ -1530,6 +1538,17 @@ package android.net {
|
||||
method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
|
||||
}
|
||||
|
||||
public static class TetheringManager.TetheringRequest {
|
||||
}
|
||||
|
||||
public static class TetheringManager.TetheringRequest.Builder {
|
||||
ctor public TetheringManager.TetheringRequest.Builder(int);
|
||||
method @NonNull public android.net.TetheringManager.TetheringRequest build();
|
||||
method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
|
||||
method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setSilentProvisioning(boolean);
|
||||
method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder useStaticIpv4Addresses(@NonNull android.net.LinkAddress);
|
||||
}
|
||||
|
||||
public class TrafficStats {
|
||||
method public static long getLoopbackRxBytes();
|
||||
method public static long getLoopbackRxPackets();
|
||||
|
||||
@@ -33,7 +33,9 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.IpSecManager.UdpEncapsulationSocket;
|
||||
import android.net.SocketKeepalive.Callback;
|
||||
import android.net.TetheringManager.StartTetheringCallback;
|
||||
import android.net.TetheringManager.TetheringEventCallback;
|
||||
import android.net.TetheringManager.TetheringRequest;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
@@ -2453,10 +2455,12 @@ public class ConnectivityManager {
|
||||
*
|
||||
* @param iface the interface name to tether.
|
||||
* @return error a {@code TETHER_ERROR} value indicating success or failure type
|
||||
* @deprecated Use {@link TetheringManager#startTethering} instead
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@Deprecated
|
||||
public int tether(String iface) {
|
||||
return getTetheringManager().tether(iface);
|
||||
}
|
||||
@@ -2513,9 +2517,12 @@ public class ConnectivityManager {
|
||||
|
||||
/**
|
||||
* Callback for use with {@link #startTethering} to find out whether tethering succeeded.
|
||||
*
|
||||
* @deprecated Use {@link TetheringManager.StartTetheringCallback} instead.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@Deprecated
|
||||
public static abstract class OnStartTetheringCallback {
|
||||
/**
|
||||
* Called when tethering has been successfully started.
|
||||
@@ -2532,9 +2539,12 @@ public class ConnectivityManager {
|
||||
* Convenient overload for
|
||||
* {@link #startTethering(int, boolean, OnStartTetheringCallback, Handler)} which passes a null
|
||||
* handler to run on the current thread's {@link Looper}.
|
||||
*
|
||||
* @deprecated Use {@link TetheringManager#startTethering} instead.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@Deprecated
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
public void startTethering(int type, boolean showProvisioningUi,
|
||||
final OnStartTetheringCallback callback) {
|
||||
@@ -2558,26 +2568,44 @@ public class ConnectivityManager {
|
||||
* @param callback an {@link OnStartTetheringCallback} which will be called to notify the caller
|
||||
* of the result of trying to tether.
|
||||
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
|
||||
*
|
||||
* @deprecated Use {@link TetheringManager#startTethering} instead.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@Deprecated
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
public void startTethering(int type, boolean showProvisioningUi,
|
||||
final OnStartTetheringCallback callback, Handler handler) {
|
||||
Preconditions.checkNotNull(callback, "OnStartTetheringCallback cannot be null.");
|
||||
|
||||
ResultReceiver wrappedCallback = new ResultReceiver(handler) {
|
||||
final Executor executor = new Executor() {
|
||||
@Override
|
||||
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||
if (resultCode == TETHER_ERROR_NO_ERROR) {
|
||||
callback.onTetheringStarted();
|
||||
public void execute(Runnable command) {
|
||||
if (handler == null) {
|
||||
command.run();
|
||||
} else {
|
||||
callback.onTetheringFailed();
|
||||
handler.post(command);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
getTetheringManager().startTethering(type, wrappedCallback, showProvisioningUi);
|
||||
final StartTetheringCallback tetheringCallback = new StartTetheringCallback() {
|
||||
@Override
|
||||
public void onTetheringStarted() {
|
||||
callback.onTetheringStarted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTetheringFailed(final int resultCode) {
|
||||
callback.onTetheringFailed();
|
||||
}
|
||||
};
|
||||
|
||||
final TetheringRequest request = new TetheringRequest.Builder(type)
|
||||
.setSilentProvisioning(!showProvisioningUi).build();
|
||||
|
||||
getTetheringManager().startTethering(request, executor, tetheringCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2750,10 +2778,12 @@ public class ConnectivityManager {
|
||||
*
|
||||
* @param enable a boolean - {@code true} to enable tethering
|
||||
* @return error a {@code TETHER_ERROR} value indicating success or failure type
|
||||
* @deprecated Use {@link TetheringManager#startTethering} instead
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@Deprecated
|
||||
public int setUsbTethering(boolean enable) {
|
||||
return getTetheringManager().setUsbTethering(enable);
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ filegroup {
|
||||
"src/android/net/ITetheringConnector.aidl",
|
||||
"src/android/net/TetheringCallbackStartedParcel.aidl",
|
||||
"src/android/net/TetheringConfigurationParcel.aidl",
|
||||
"src/android/net/TetheringRequestParcel.aidl",
|
||||
"src/android/net/TetherStatesParcel.aidl",
|
||||
],
|
||||
path: "src"
|
||||
|
||||
@@ -17,6 +17,7 @@ package android.net;
|
||||
|
||||
import android.net.IIntResultListener;
|
||||
import android.net.ITetheringEventCallback;
|
||||
import android.net.TetheringRequestParcel;
|
||||
import android.os.ResultReceiver;
|
||||
|
||||
/** @hide */
|
||||
@@ -27,8 +28,8 @@ oneway interface ITetheringConnector {
|
||||
|
||||
void setUsbTethering(boolean enable, String callerPkg, IIntResultListener receiver);
|
||||
|
||||
void startTethering(int type, in ResultReceiver receiver, boolean showProvisioningUi,
|
||||
String callerPkg);
|
||||
void startTethering(in TetheringRequestParcel request, String callerPkg,
|
||||
IIntResultListener receiver);
|
||||
|
||||
void stopTethering(int type, String callerPkg, IIntResultListener receiver);
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package android.net;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
@@ -325,28 +326,172 @@ public class TetheringManager {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Use with {@link #startTethering} to specify additional parameters when starting tethering.
|
||||
*/
|
||||
public static class TetheringRequest {
|
||||
/** A configuration set for TetheringRequest. */
|
||||
private final TetheringRequestParcel mRequestParcel;
|
||||
|
||||
private TetheringRequest(final TetheringRequestParcel request) {
|
||||
mRequestParcel = request;
|
||||
}
|
||||
|
||||
/** Builder used to create TetheringRequest. */
|
||||
public static class Builder {
|
||||
private final TetheringRequestParcel mBuilderParcel;
|
||||
|
||||
/** Default constructor of Builder. */
|
||||
public Builder(final int type) {
|
||||
mBuilderParcel = new TetheringRequestParcel();
|
||||
mBuilderParcel.tetheringType = type;
|
||||
mBuilderParcel.localIPv4Address = null;
|
||||
mBuilderParcel.exemptFromEntitlementCheck = false;
|
||||
mBuilderParcel.showProvisioningUi = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure tethering with static IPv4 assignment (with DHCP disabled).
|
||||
*
|
||||
* @param localIPv4Address The preferred local IPv4 address to use.
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
@NonNull
|
||||
public Builder useStaticIpv4Addresses(@NonNull final LinkAddress localIPv4Address) {
|
||||
mBuilderParcel.localIPv4Address = localIPv4Address;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Start tethering without entitlement checks. */
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
@NonNull
|
||||
public Builder setExemptFromEntitlementCheck(boolean exempt) {
|
||||
mBuilderParcel.exemptFromEntitlementCheck = exempt;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Start tethering without showing the provisioning UI. */
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
@NonNull
|
||||
public Builder setSilentProvisioning(boolean silent) {
|
||||
mBuilderParcel.showProvisioningUi = silent;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Build {@link TetheringRequest] with the currently set configuration. */
|
||||
@NonNull
|
||||
public TetheringRequest build() {
|
||||
return new TetheringRequest(mBuilderParcel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a TetheringRequestParcel from the configuration
|
||||
* @hide
|
||||
*/
|
||||
public TetheringRequestParcel getParcel() {
|
||||
return mRequestParcel;
|
||||
}
|
||||
|
||||
/** String of TetheringRequest detail. */
|
||||
public String toString() {
|
||||
return "TetheringRequest [ type= " + mRequestParcel.tetheringType
|
||||
+ ", localIPv4Address= " + mRequestParcel.localIPv4Address
|
||||
+ ", exemptFromEntitlementCheck= "
|
||||
+ mRequestParcel.exemptFromEntitlementCheck + ", showProvisioningUi= "
|
||||
+ mRequestParcel.showProvisioningUi + " ]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for use with {@link #startTethering} to find out whether tethering succeeded.
|
||||
*/
|
||||
public abstract static class StartTetheringCallback {
|
||||
/**
|
||||
* Called when tethering has been successfully started.
|
||||
*/
|
||||
public void onTetheringStarted() {}
|
||||
|
||||
/**
|
||||
* Called when starting tethering failed.
|
||||
*
|
||||
* @param resultCode One of the {@code TETHER_ERROR_*} constants.
|
||||
*/
|
||||
public void onTetheringFailed(final int resultCode) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts tethering and runs tether provisioning for the given type if needed. If provisioning
|
||||
* fails, stopTethering will be called automatically.
|
||||
* @hide
|
||||
*
|
||||
* <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will
|
||||
* fail if a tethering entitlement check is required.
|
||||
*
|
||||
* @param request a {@link TetheringRequest} which can specify the preferred configuration.
|
||||
* @param executor {@link Executor} to specify the thread upon which the callback of
|
||||
* TetheringRequest will be invoked.
|
||||
* @param callback A callback that will be called to indicate the success status of the
|
||||
* tethering start request.
|
||||
*/
|
||||
// TODO: improve the usage of ResultReceiver, b/145096122
|
||||
public void startTethering(final int type, @NonNull final ResultReceiver receiver,
|
||||
final boolean showProvisioningUi) {
|
||||
@RequiresPermission(anyOf = {
|
||||
android.Manifest.permission.TETHER_PRIVILEGED,
|
||||
android.Manifest.permission.WRITE_SETTINGS
|
||||
})
|
||||
public void startTethering(@NonNull final TetheringRequest request,
|
||||
@NonNull final Executor executor, @NonNull final StartTetheringCallback callback) {
|
||||
final String callerPkg = mContext.getOpPackageName();
|
||||
Log.i(TAG, "startTethering caller:" + callerPkg);
|
||||
|
||||
final IIntResultListener listener = new IIntResultListener.Stub() {
|
||||
@Override
|
||||
public void onResult(final int resultCode) {
|
||||
executor.execute(() -> {
|
||||
if (resultCode == TETHER_ERROR_NO_ERROR) {
|
||||
callback.onTetheringStarted();
|
||||
} else {
|
||||
callback.onTetheringFailed(resultCode);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
try {
|
||||
mConnector.startTethering(type, receiver, showProvisioningUi, callerPkg);
|
||||
mConnector.startTethering(request.getParcel(), callerPkg, listener);
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts tethering and runs tether provisioning for the given type if needed. If provisioning
|
||||
* fails, stopTethering will be called automatically.
|
||||
*
|
||||
* <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will
|
||||
* fail if a tethering entitlement check is required.
|
||||
*
|
||||
* @param type The tethering type, on of the {@code TetheringManager#TETHERING_*} constants.
|
||||
* @param executor {@link Executor} to specify the thread upon which the callback of
|
||||
* TetheringRequest will be invoked.
|
||||
*/
|
||||
@RequiresPermission(anyOf = {
|
||||
android.Manifest.permission.TETHER_PRIVILEGED,
|
||||
android.Manifest.permission.WRITE_SETTINGS
|
||||
})
|
||||
public void startTethering(int type, @NonNull final Executor executor,
|
||||
@NonNull final StartTetheringCallback callback) {
|
||||
startTethering(new TetheringRequest.Builder(type).build(), executor, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops tethering for the given type. Also cancels any provisioning rechecks for that type if
|
||||
* applicable.
|
||||
*
|
||||
* <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will
|
||||
* fail if a tethering entitlement check is required.
|
||||
*/
|
||||
@RequiresPermission(anyOf = {
|
||||
android.Manifest.permission.TETHER_PRIVILEGED,
|
||||
android.Manifest.permission.WRITE_SETTINGS
|
||||
})
|
||||
public void stopTethering(final int type) {
|
||||
final String callerPkg = mContext.getOpPackageName();
|
||||
Log.i(TAG, "stopTethering caller:" + callerPkg);
|
||||
@@ -386,6 +531,9 @@ public class TetheringManager {
|
||||
* {@link #TETHER_ERROR_ENTITLEMENT_UNKNOWN} will be returned. If {@code showEntitlementUi} is
|
||||
* true, entitlement will be run.
|
||||
*
|
||||
* <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will
|
||||
* fail if a tethering entitlement check is required.
|
||||
*
|
||||
* @param type the downstream type of tethering. Must be one of {@code #TETHERING_*} constants.
|
||||
* @param showEntitlementUi a boolean indicating whether to run UI-based entitlement check.
|
||||
* @param executor the executor on which callback will be invoked.
|
||||
@@ -393,7 +541,10 @@ public class TetheringManager {
|
||||
* notify the caller of the result of entitlement check. The listener may be called zero
|
||||
* or one time.
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
@RequiresPermission(anyOf = {
|
||||
android.Manifest.permission.TETHER_PRIVILEGED,
|
||||
android.Manifest.permission.WRITE_SETTINGS
|
||||
})
|
||||
public void requestLatestTetheringEntitlementResult(int type, boolean showEntitlementUi,
|
||||
@NonNull Executor executor,
|
||||
@NonNull final OnTetheringEntitlementResultListener listener) {
|
||||
@@ -562,6 +713,7 @@ public class TetheringManager {
|
||||
* @param executor the executor on which callback will be invoked.
|
||||
* @param callback the callback to be called when tethering has change events.
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
public void registerTetheringEventCallback(@NonNull Executor executor,
|
||||
@NonNull TetheringEventCallback callback) {
|
||||
final String callerPkg = mContext.getOpPackageName();
|
||||
@@ -669,6 +821,10 @@ public class TetheringManager {
|
||||
*
|
||||
* @param callback previously registered callback.
|
||||
*/
|
||||
@RequiresPermission(anyOf = {
|
||||
Manifest.permission.TETHER_PRIVILEGED,
|
||||
Manifest.permission.ACCESS_NETWORK_STATE
|
||||
})
|
||||
public void unregisterTetheringEventCallback(@NonNull final TetheringEventCallback callback) {
|
||||
final String callerPkg = mContext.getOpPackageName();
|
||||
Log.i(TAG, "unregisterTetheringEventCallback caller:" + callerPkg);
|
||||
@@ -833,7 +989,14 @@ public class TetheringManager {
|
||||
|
||||
/**
|
||||
* Stop all active tethering.
|
||||
*
|
||||
* <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will
|
||||
* fail if a tethering entitlement check is required.
|
||||
*/
|
||||
@RequiresPermission(anyOf = {
|
||||
android.Manifest.permission.TETHER_PRIVILEGED,
|
||||
android.Manifest.permission.WRITE_SETTINGS
|
||||
})
|
||||
public void stopAllTethering() {
|
||||
final String callerPkg = mContext.getOpPackageName();
|
||||
Log.i(TAG, "stopAllTethering caller:" + callerPkg);
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.net.LinkAddress;
|
||||
|
||||
/**
|
||||
* Configuration details for requesting tethering.
|
||||
* @hide
|
||||
*/
|
||||
parcelable TetheringRequestParcel {
|
||||
int tetheringType;
|
||||
LinkAddress localIPv4Address;
|
||||
boolean exemptFromEntitlementCheck;
|
||||
boolean showProvisioningUi;
|
||||
}
|
||||
@@ -66,6 +66,7 @@ import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.IIntResultListener;
|
||||
import android.net.INetd;
|
||||
import android.net.ITetheringEventCallback;
|
||||
import android.net.IpPrefix;
|
||||
@@ -76,6 +77,7 @@ import android.net.NetworkInfo;
|
||||
import android.net.TetherStatesParcel;
|
||||
import android.net.TetheringCallbackStartedParcel;
|
||||
import android.net.TetheringConfigurationParcel;
|
||||
import android.net.TetheringRequestParcel;
|
||||
import android.net.ip.IpServer;
|
||||
import android.net.shared.NetdUtils;
|
||||
import android.net.util.BaseNetdUnsolicitedEventListener;
|
||||
@@ -424,9 +426,10 @@ public class Tethering {
|
||||
}
|
||||
}
|
||||
|
||||
void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
|
||||
mEntitlementMgr.startProvisioningIfNeeded(type, showProvisioningUi);
|
||||
enableTetheringInternal(type, true /* enabled */, receiver);
|
||||
void startTethering(final TetheringRequestParcel request, final IIntResultListener listener) {
|
||||
mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType,
|
||||
request.showProvisioningUi);
|
||||
enableTetheringInternal(request.tetheringType, true /* enabled */, listener);
|
||||
}
|
||||
|
||||
void stopTethering(int type) {
|
||||
@@ -438,29 +441,32 @@ public class Tethering {
|
||||
* Enables or disables tethering for the given type. If provisioning is required, it will
|
||||
* schedule provisioning rechecks for the specified interface.
|
||||
*/
|
||||
private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) {
|
||||
private void enableTetheringInternal(int type, boolean enable,
|
||||
final IIntResultListener listener) {
|
||||
int result;
|
||||
switch (type) {
|
||||
case TETHERING_WIFI:
|
||||
result = setWifiTethering(enable);
|
||||
sendTetherResult(receiver, result);
|
||||
sendTetherResult(listener, result);
|
||||
break;
|
||||
case TETHERING_USB:
|
||||
result = setUsbTethering(enable);
|
||||
sendTetherResult(receiver, result);
|
||||
sendTetherResult(listener, result);
|
||||
break;
|
||||
case TETHERING_BLUETOOTH:
|
||||
setBluetoothTethering(enable, receiver);
|
||||
setBluetoothTethering(enable, listener);
|
||||
break;
|
||||
default:
|
||||
Log.w(TAG, "Invalid tether type.");
|
||||
sendTetherResult(receiver, TETHER_ERROR_UNKNOWN_IFACE);
|
||||
sendTetherResult(listener, TETHER_ERROR_UNKNOWN_IFACE);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendTetherResult(ResultReceiver receiver, int result) {
|
||||
if (receiver != null) {
|
||||
receiver.send(result, null);
|
||||
private void sendTetherResult(final IIntResultListener listener, int result) {
|
||||
if (listener != null) {
|
||||
try {
|
||||
listener.onResult(result);
|
||||
} catch (RemoteException e) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,12 +492,12 @@ public class Tethering {
|
||||
return TETHER_ERROR_MASTER_ERROR;
|
||||
}
|
||||
|
||||
private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) {
|
||||
private void setBluetoothTethering(final boolean enable, final IIntResultListener listener) {
|
||||
final BluetoothAdapter adapter = mDeps.getBluetoothAdapter();
|
||||
if (adapter == null || !adapter.isEnabled()) {
|
||||
Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: "
|
||||
+ (adapter == null));
|
||||
sendTetherResult(receiver, TETHER_ERROR_SERVICE_UNAVAIL);
|
||||
sendTetherResult(listener, TETHER_ERROR_SERVICE_UNAVAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -520,7 +526,7 @@ public class Tethering {
|
||||
final int result = (((BluetoothPan) proxy).isTetheringOn() == enable)
|
||||
? TETHER_ERROR_NO_ERROR
|
||||
: TETHER_ERROR_MASTER_ERROR;
|
||||
sendTetherResult(receiver, result);
|
||||
sendTetherResult(listener, result);
|
||||
adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
|
||||
}
|
||||
}, BluetoothProfile.PAN);
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.net.ITetheringConnector;
|
||||
import android.net.ITetheringEventCallback;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.TetheringRequestParcel;
|
||||
import android.net.dhcp.DhcpServerCallbacks;
|
||||
import android.net.dhcp.DhcpServingParamsParcel;
|
||||
import android.net.ip.IpServer;
|
||||
@@ -143,11 +144,11 @@ public class TetheringService extends Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi,
|
||||
String callerPkg) {
|
||||
if (checkAndNotifyCommonError(callerPkg, receiver)) return;
|
||||
public void startTethering(TetheringRequestParcel request, String callerPkg,
|
||||
IIntResultListener listener) {
|
||||
if (checkAndNotifyCommonError(callerPkg, listener)) return;
|
||||
|
||||
mTethering.startTethering(type, receiver, showProvisioningUi);
|
||||
mTethering.startTethering(request, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -88,6 +88,7 @@ import android.net.RouteInfo;
|
||||
import android.net.TetherStatesParcel;
|
||||
import android.net.TetheringCallbackStartedParcel;
|
||||
import android.net.TetheringConfigurationParcel;
|
||||
import android.net.TetheringRequestParcel;
|
||||
import android.net.dhcp.DhcpServerCallbacks;
|
||||
import android.net.dhcp.DhcpServingParamsParcel;
|
||||
import android.net.dhcp.IDhcpServer;
|
||||
@@ -468,6 +469,16 @@ public class TetheringTest {
|
||||
return new Tethering(mTetheringDependencies);
|
||||
}
|
||||
|
||||
private TetheringRequestParcel createTetheringRquestParcel(final int type) {
|
||||
final TetheringRequestParcel request = new TetheringRequestParcel();
|
||||
request.tetheringType = type;
|
||||
request.localIPv4Address = null;
|
||||
request.exemptFromEntitlementCheck = false;
|
||||
request.showProvisioningUi = false;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mServiceContext.unregisterReceiver(mBroadcastReceiver);
|
||||
@@ -573,7 +584,7 @@ public class TetheringTest {
|
||||
.thenReturn(upstreamState);
|
||||
|
||||
// Emulate pressing the USB tethering button in Settings UI.
|
||||
mTethering.startTethering(TETHERING_USB, null, false);
|
||||
mTethering.startTethering(createTetheringRquestParcel(TETHERING_USB), null);
|
||||
mLooper.dispatchAll();
|
||||
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
|
||||
|
||||
@@ -819,7 +830,7 @@ public class TetheringTest {
|
||||
when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
|
||||
|
||||
// Emulate pressing the WiFi tethering button.
|
||||
mTethering.startTethering(TETHERING_WIFI, null, false);
|
||||
mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null);
|
||||
mLooper.dispatchAll();
|
||||
verify(mWifiManager, times(1)).startSoftAp(null);
|
||||
verifyNoMoreInteractions(mWifiManager);
|
||||
@@ -846,7 +857,7 @@ public class TetheringTest {
|
||||
when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
|
||||
|
||||
// Emulate pressing the WiFi tethering button.
|
||||
mTethering.startTethering(TETHERING_WIFI, null, false);
|
||||
mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null);
|
||||
mLooper.dispatchAll();
|
||||
verify(mWifiManager, times(1)).startSoftAp(null);
|
||||
verifyNoMoreInteractions(mWifiManager);
|
||||
@@ -923,7 +934,7 @@ public class TetheringTest {
|
||||
doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
|
||||
|
||||
// Emulate pressing the WiFi tethering button.
|
||||
mTethering.startTethering(TETHERING_WIFI, null, false);
|
||||
mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null);
|
||||
mLooper.dispatchAll();
|
||||
verify(mWifiManager, times(1)).startSoftAp(null);
|
||||
verifyNoMoreInteractions(mWifiManager);
|
||||
@@ -1188,7 +1199,7 @@ public class TetheringTest {
|
||||
tetherState = callback.pollTetherStatesChanged();
|
||||
assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME});
|
||||
|
||||
mTethering.startTethering(TETHERING_WIFI, null, false);
|
||||
mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null);
|
||||
sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
|
||||
mLooper.dispatchAll();
|
||||
tetherState = callback.pollTetherStatesChanged();
|
||||
|
||||
Reference in New Issue
Block a user