Merge changes I3cb9b5ed,I91196e43 into main
* changes:
no-op: Pipe TetheringRequest through enableTetheringInternal
no-op: Refactor bluetooth tethering listener
diff --git a/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
index f123dca..0ac97f0 100644
--- a/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
+++ b/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
@@ -333,6 +333,11 @@
public static final int TETHER_ERROR_UNKNOWN_REQUEST = 17;
@FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG)
public static final int TETHER_ERROR_DUPLICATE_REQUEST = 18;
+ /**
+ * Never used outside Tethering.java.
+ * @hide
+ */
+ public static final int TETHER_ERROR_BLUETOOTH_SERVICE_PENDING = 19;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index c0192dd..b50831d 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -43,6 +43,7 @@
import static android.net.TetheringManager.TETHERING_WIFI;
import static android.net.TetheringManager.TETHERING_WIFI_P2P;
import static android.net.TetheringManager.TETHERING_WIGIG;
+import static android.net.TetheringManager.TETHER_ERROR_BLUETOOTH_SERVICE_PENDING;
import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
@@ -707,8 +708,7 @@
// If tethering is already enabled with a different request,
// disable before re-enabling.
if (unfinishedRequest != null && !unfinishedRequest.equalsIgnoreUidPackage(request)) {
- enableTetheringInternal(type, false /* disabled */,
- unfinishedRequest.getInterfaceName(), null);
+ enableTetheringInternal(false /* disabled */, unfinishedRequest, null);
mEntitlementMgr.stopProvisioningIfNeeded(type);
}
mPendingTetheringRequests.put(type, request);
@@ -719,7 +719,7 @@
mEntitlementMgr.startProvisioningIfNeeded(type,
request.getShouldShowEntitlementUi());
}
- enableTetheringInternal(type, true /* enabled */, request.getInterfaceName(), listener);
+ enableTetheringInternal(true /* enabled */, request, listener);
mTetheringMetrics.createBuilder(type, callerPkg);
});
}
@@ -766,7 +766,10 @@
void stopTetheringInternal(int type) {
mPendingTetheringRequests.remove(type);
- enableTetheringInternal(type, false /* disabled */, null, null);
+ // Using a placeholder here is ok since none of the disable APIs use the request for
+ // anything. We simply need the tethering type to know which link layer to poke for removal.
+ // TODO: Remove the placeholder here and loop through each pending/serving request.
+ enableTetheringInternal(false /* disabled */, createPlaceholderRequest(type), null);
mEntitlementMgr.stopProvisioningIfNeeded(type);
}
@@ -774,9 +777,10 @@
* 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,
- String iface, final IIntResultListener listener) {
- int result = TETHER_ERROR_NO_ERROR;
+ private void enableTetheringInternal(boolean enable, @NonNull final TetheringRequest request,
+ final IIntResultListener listener) {
+ final int type = request.getTetheringType();
+ final int result;
switch (type) {
case TETHERING_WIFI:
result = setWifiTethering(enable);
@@ -785,7 +789,7 @@
result = setUsbTethering(enable);
break;
case TETHERING_BLUETOOTH:
- setBluetoothTethering(enable, listener);
+ result = setBluetoothTethering(enable, listener);
break;
case TETHERING_NCM:
result = setNcmTethering(enable);
@@ -794,17 +798,17 @@
result = setEthernetTethering(enable);
break;
case TETHERING_VIRTUAL:
- result = setVirtualMachineTethering(enable, iface);
+ result = setVirtualMachineTethering(enable, request);
break;
default:
Log.w(TAG, "Invalid tether type.");
result = TETHER_ERROR_UNKNOWN_TYPE;
}
- // The result of Bluetooth tethering will be sent by #setBluetoothTethering.
- if (type != TETHERING_BLUETOOTH) {
- sendTetherResult(listener, result, type);
- }
+ // The result of Bluetooth tethering will be sent after the pan service connects.
+ if (result == TETHER_ERROR_BLUETOOTH_SERVICE_PENDING) return;
+
+ sendTetherResult(listener, result, type);
}
private void sendTetherResult(final IIntResultListener listener, final int result,
@@ -843,13 +847,12 @@
return TETHER_ERROR_INTERNAL_ERROR;
}
- private void setBluetoothTethering(final boolean enable, final IIntResultListener listener) {
+ private int 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(listener, TETHER_ERROR_SERVICE_UNAVAIL, TETHERING_BLUETOOTH);
- return;
+ return TETHER_ERROR_SERVICE_UNAVAIL;
}
if (mBluetoothPanListener != null && mBluetoothPanListener.isConnected()) {
@@ -857,8 +860,7 @@
// When bluetooth tethering is enabled, any time a PAN client pairs with this
// host, bluetooth will bring up a bt-pan interface and notify tethering to
// enable IP serving.
- setBluetoothTetheringSettings(mBluetoothPan, enable, listener);
- return;
+ return setBluetoothTetheringSettings(mBluetoothPan, enable);
}
if (!enable) {
@@ -870,8 +872,7 @@
TETHERING_BLUETOOTH);
}
mPendingPanRequestListeners.clear();
- sendTetherResult(listener, TETHER_ERROR_NO_ERROR, TETHERING_BLUETOOTH);
- return;
+ return TETHER_ERROR_NO_ERROR;
}
mPendingPanRequestListeners.add(listener);
@@ -883,6 +884,7 @@
mBluetoothPanListener = new PanServiceListener();
adapter.getProfileProxy(mContext, mBluetoothPanListener, BluetoothProfile.PAN);
}
+ return TETHER_ERROR_BLUETOOTH_SERVICE_PENDING;
}
private class PanServiceListener implements ServiceListener {
@@ -900,8 +902,9 @@
mIsConnected = true;
for (IIntResultListener pendingListener : mPendingPanRequestListeners) {
- setBluetoothTetheringSettings(mBluetoothPan, true /* enable */,
- pendingListener);
+ final int result = setBluetoothTetheringSettings(mBluetoothPan,
+ true /* enable */);
+ sendTetherResult(pendingListener, result, TETHERING_BLUETOOTH);
}
mPendingPanRequestListeners.clear();
});
@@ -930,8 +933,8 @@
}
}
- private void setBluetoothTetheringSettings(@NonNull final BluetoothPan bluetoothPan,
- final boolean enable, final IIntResultListener listener) {
+ private int setBluetoothTetheringSettings(@NonNull final BluetoothPan bluetoothPan,
+ final boolean enable) {
if (SdkLevel.isAtLeastT()) {
changeBluetoothTetheringSettings(bluetoothPan, enable);
} else {
@@ -940,9 +943,8 @@
// Enabling bluetooth tethering settings can silently fail. Send internal error if the
// result is not expected.
- final int result = bluetoothPan.isTetheringOn() == enable
+ return bluetoothPan.isTetheringOn() == enable
? TETHER_ERROR_NO_ERROR : TETHER_ERROR_INTERNAL_ERROR;
- sendTetherResult(listener, result, TETHERING_BLUETOOTH);
}
private void changeBluetoothTetheringSettingsPreT(@NonNull final BluetoothPan bluetoothPan,
@@ -1061,14 +1063,15 @@
}
}
- private int setVirtualMachineTethering(final boolean enable, String iface) {
+ private int setVirtualMachineTethering(final boolean enable,
+ @NonNull final TetheringRequest request) {
+ final String iface = request.getInterfaceName();
if (enable) {
if (TextUtils.isEmpty(iface)) {
mConfiguredVirtualIface = "avf_tap_fixed";
} else {
mConfiguredVirtualIface = iface;
}
- final TetheringRequest request = getOrCreatePendingTetheringRequest(TETHERING_VIRTUAL);
enableIpServing(request, mConfiguredVirtualIface);
} else if (mConfiguredVirtualIface != null) {
ensureIpServerStopped(mConfiguredVirtualIface);
@@ -1101,6 +1104,19 @@
}
/**
+ * Create a placeholder request. This is used in case we try to find a pending request but there
+ * is none (e.g. stopTethering removed a pending request), or for cases where we only have the
+ * tethering type (e.g. stopTethering(int)).
+ */
+ @NonNull
+ private TetheringRequest createPlaceholderRequest(int type) {
+ final TetheringRequest request = new TetheringRequest.Builder(type).build();
+ request.getParcel().requestType = TetheringRequest.REQUEST_TYPE_LEGACY;
+ request.getParcel().connectivityScope = CONNECTIVITY_SCOPE_GLOBAL;
+ return request;
+ }
+
+ /**
* Gets the TetheringRequest that #startTethering was called with but is waiting for the link
* layer event to indicate the interface is available to tether.
* Note: There are edge cases where the pending request is absent and we must temporarily
@@ -1116,9 +1132,7 @@
Log.w(TAG, "No pending TetheringRequest for type " + type + " found, creating a placeholder"
+ " request");
- TetheringRequest placeholder = new TetheringRequest.Builder(type).build();
- placeholder.getParcel().requestType = REQUEST_TYPE_PLACEHOLDER;
- return placeholder;
+ return createPlaceholderRequest(type);
}
private void handleLegacyTether(String iface, final IIntResultListener listener) {
@@ -2414,9 +2428,14 @@
break;
}
case EVENT_REQUEST_CHANGE_DOWNSTREAM: {
- final int tetheringType = message.arg1;
+ final int type = message.arg1;
final Boolean enabled = (Boolean) message.obj;
- enableTetheringInternal(tetheringType, enabled, null, null);
+ // Using a placeholder here is ok since we just need to the type of
+ // tethering to poke the link layer. When the link layer comes up, we won't
+ // have a pending request to use, but this matches the historical behavior.
+ // TODO: Get the TetheringRequest from IpServer and make sure to put it in
+ // the pending list too.
+ enableTetheringInternal(enabled, createPlaceholderRequest(type), null);
break;
}
default: