Merge "Allows the caller to specify configuration by TetheringRequest"

This commit is contained in:
Remi NGUYEN VAN
2020-01-24 02:38:52 +00:00
committed by Android (Google) Code Review
10 changed files with 334 additions and 53 deletions

View File

@@ -6095,8 +6095,8 @@ package android.net {
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_AIRPLANE_MODE, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean);
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.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);
@@ -6112,10 +6112,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 {
@@ -6523,11 +6523,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";
@@ -6560,6 +6562,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);
@@ -6577,6 +6585,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();

View File

@@ -1727,11 +1727,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";
@@ -1764,6 +1766,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);
@@ -1781,6 +1789,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();

View File

@@ -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;
@@ -2452,10 +2454,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);
}
@@ -2512,9 +2516,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.
@@ -2531,9 +2538,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) {
@@ -2557,26 +2567,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);
}
/**
@@ -2749,10 +2777,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);
}

View File

@@ -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"

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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.startTetheredHotspot(any(SoftApConfiguration.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)).startTetheredHotspot(null);
verifyNoMoreInteractions(mWifiManager);
@@ -846,7 +857,7 @@ public class TetheringTest {
when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.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)).startTetheredHotspot(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)).startTetheredHotspot(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();