Merge "Add methods to distinguish TetheringRequest types" into main
This commit is contained in:
commit
134d017940
6 changed files with 124 additions and 22 deletions
|
|
@ -807,6 +807,46 @@ public class TetheringManager {
|
|||
*/
|
||||
@SuppressLint("UnflaggedApi")
|
||||
public static final class TetheringRequest implements Parcelable {
|
||||
/**
|
||||
* Tethering started by an explicit call to startTethering.
|
||||
* @hide
|
||||
*/
|
||||
public static final int REQUEST_TYPE_EXPLICIT = 0;
|
||||
|
||||
/**
|
||||
* Tethering implicitly started by broadcasts (LOHS and P2P). Can never be pending.
|
||||
* @hide
|
||||
*/
|
||||
public static final int REQUEST_TYPE_IMPLICIT = 1;
|
||||
|
||||
/**
|
||||
* Tethering started by the legacy tether() call. Can only happen on V-.
|
||||
* @hide
|
||||
*/
|
||||
public static final int REQUEST_TYPE_LEGACY = 2;
|
||||
|
||||
/**
|
||||
* Tethering started but there was no pending request found. This may happen if Tethering is
|
||||
* started and immediately stopped before the link layer goes up, or if we get a link layer
|
||||
* event without a prior call to startTethering (e.g. adb shell cmd wifi start-softap).
|
||||
* @hide
|
||||
*/
|
||||
public static final int REQUEST_TYPE_PLACEHOLDER = 3;
|
||||
|
||||
/**
|
||||
* Type of request, used to keep track of whether the request was explicitly sent by
|
||||
* startTethering, implicitly created by broadcasts, or via legacy tether().
|
||||
* @hide
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = "TYPE_", value = {
|
||||
REQUEST_TYPE_EXPLICIT,
|
||||
REQUEST_TYPE_IMPLICIT,
|
||||
REQUEST_TYPE_LEGACY,
|
||||
REQUEST_TYPE_PLACEHOLDER,
|
||||
})
|
||||
public @interface RequestType {}
|
||||
|
||||
/** A configuration set for TetheringRequest. */
|
||||
private final TetheringRequestParcel mRequestParcel;
|
||||
|
||||
|
|
@ -866,6 +906,7 @@ public class TetheringManager {
|
|||
mBuilderParcel.uid = Process.INVALID_UID;
|
||||
mBuilderParcel.softApConfig = null;
|
||||
mBuilderParcel.interfaceName = null;
|
||||
mBuilderParcel.requestType = REQUEST_TYPE_EXPLICIT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1160,6 +1201,14 @@ public class TetheringManager {
|
|||
return mRequestParcel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the request.
|
||||
* @hide
|
||||
*/
|
||||
public @RequestType int getRequestType() {
|
||||
return mRequestParcel.requestType;
|
||||
}
|
||||
|
||||
/**
|
||||
* String of TetheringRequest detail.
|
||||
* @hide
|
||||
|
|
@ -1168,6 +1217,13 @@ public class TetheringManager {
|
|||
public String toString() {
|
||||
StringJoiner sj = new StringJoiner(", ", "TetheringRequest[ ", " ]");
|
||||
sj.add(typeToString(mRequestParcel.tetheringType));
|
||||
if (mRequestParcel.requestType == REQUEST_TYPE_IMPLICIT) {
|
||||
sj.add("IMPLICIT");
|
||||
} else if (mRequestParcel.requestType == REQUEST_TYPE_LEGACY) {
|
||||
sj.add("LEGACY");
|
||||
} else if (mRequestParcel.requestType == REQUEST_TYPE_PLACEHOLDER) {
|
||||
sj.add("PLACEHOLDER");
|
||||
}
|
||||
if (mRequestParcel.localIPv4Address != null) {
|
||||
sj.add("localIpv4Address=" + mRequestParcel.localIPv4Address);
|
||||
}
|
||||
|
|
@ -1217,7 +1273,8 @@ public class TetheringManager {
|
|||
public boolean equalsIgnoreUidPackage(TetheringRequest otherRequest) {
|
||||
TetheringRequestParcel parcel = getParcel();
|
||||
TetheringRequestParcel otherParcel = otherRequest.getParcel();
|
||||
return parcel.tetheringType == otherParcel.tetheringType
|
||||
return parcel.requestType == otherParcel.requestType
|
||||
&& parcel.tetheringType == otherParcel.tetheringType
|
||||
&& Objects.equals(parcel.localIPv4Address, otherParcel.localIPv4Address)
|
||||
&& Objects.equals(parcel.staticClientAddress, otherParcel.staticClientAddress)
|
||||
&& parcel.exemptFromEntitlementCheck == otherParcel.exemptFromEntitlementCheck
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import android.net.wifi.SoftApConfiguration;
|
|||
* @hide
|
||||
*/
|
||||
parcelable TetheringRequestParcel {
|
||||
int requestType;
|
||||
int tetheringType;
|
||||
LinkAddress localIPv4Address;
|
||||
LinkAddress staticClientAddress;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_TYPE;
|
|||
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
|
||||
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
|
||||
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
|
||||
import static android.net.TetheringManager.TetheringRequest.REQUEST_TYPE_PLACEHOLDER;
|
||||
import static android.net.TetheringManager.toIfaces;
|
||||
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
|
||||
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
|
||||
|
|
@ -1030,6 +1031,49 @@ public class Tethering {
|
|||
return TETHER_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a legacy tethering request for calls to the legacy tether() API, which doesn't take an
|
||||
* explicit request.
|
||||
*/
|
||||
private TetheringRequest createLegacyTetheringRequest(int type, int connectivityScope) {
|
||||
final TetheringRequest request = new TetheringRequest.Builder(type).build();
|
||||
request.getParcel().requestType = TetheringRequest.REQUEST_TYPE_LEGACY;
|
||||
request.getParcel().connectivityScope = connectivityScope;
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a local-only implicit tethering request. This is used for Wifi local-only hotspot and
|
||||
* Wifi P2P, which start tethering based on the WIFI_(AP/P2P)_STATE_CHANGED broadcasts.
|
||||
*/
|
||||
@NonNull
|
||||
private TetheringRequest createImplicitLocalOnlyTetheringRequest(int type) {
|
||||
final TetheringRequest request = new TetheringRequest.Builder(type).build();
|
||||
request.getParcel().requestType = TetheringRequest.REQUEST_TYPE_IMPLICIT;
|
||||
request.getParcel().connectivityScope = CONNECTIVITY_SCOPE_LOCAL;
|
||||
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
|
||||
* synthesize a placeholder request, such as if stopTethering was called before link layer
|
||||
* went up, or if the link layer goes up without us poking it (e.g. adb shell cmd wifi
|
||||
* start-softap).
|
||||
*/
|
||||
@NonNull
|
||||
private TetheringRequest getOrCreatePendingTetheringRequest(int type) {
|
||||
TetheringRequest pending = mActiveTetheringRequests.get(type);
|
||||
if (pending != null) return pending;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy tether API that starts tethering with CONNECTIVITY_SCOPE_GLOBAL on the given iface.
|
||||
*
|
||||
|
|
@ -1043,7 +1087,7 @@ public class Tethering {
|
|||
* WIFI_(AP/P2P_STATE_CHANGED broadcasts, which makes this API redundant for those types unless
|
||||
* those broadcasts are disabled by OEM.
|
||||
*/
|
||||
void tether(String iface, int requestedState, final IIntResultListener listener) {
|
||||
void legacyTether(String iface, int requestedState, final IIntResultListener listener) {
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||
// After V, the TetheringManager and ConnectivityManager tether and untether methods
|
||||
// throw UnsupportedOperationException, so this cannot happen in normal use. Ensure
|
||||
|
|
@ -1052,7 +1096,7 @@ public class Tethering {
|
|||
return;
|
||||
}
|
||||
mHandler.post(() -> {
|
||||
int result = tether(iface, requestedState);
|
||||
int result = tetherInternal(iface, requestedState);
|
||||
switch (ifaceNameToType(iface)) {
|
||||
case TETHERING_WIFI:
|
||||
TerribleErrorLog.logTerribleError(TetheringStatsLog::write,
|
||||
|
|
@ -1088,7 +1132,7 @@ public class Tethering {
|
|||
});
|
||||
}
|
||||
|
||||
private int tether(String iface, int requestedState) {
|
||||
private int tetherInternal(String iface, int requestedState) {
|
||||
if (DBG) Log.d(TAG, "Tethering " + iface);
|
||||
TetherState tetherState = mTetherStates.get(iface);
|
||||
if (tetherState == null) {
|
||||
|
|
@ -1114,7 +1158,7 @@ public class Tethering {
|
|||
return TETHER_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
void untether(String iface, final IIntResultListener listener) {
|
||||
void legacyUntether(String iface, final IIntResultListener listener) {
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||
// After V, the TetheringManager and ConnectivityManager tether and untether methods
|
||||
// throw UnsupportedOperationException, so this cannot happen in normal use. Ensure
|
||||
|
|
@ -1124,13 +1168,13 @@ public class Tethering {
|
|||
}
|
||||
mHandler.post(() -> {
|
||||
try {
|
||||
listener.onResult(untether(iface));
|
||||
listener.onResult(legacyUntetherInternal(iface));
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
int untether(String iface) {
|
||||
int legacyUntetherInternal(String iface) {
|
||||
if (DBG) Log.d(TAG, "Untethering " + iface);
|
||||
TetherState tetherState = mTetherStates.get(iface);
|
||||
if (tetherState == null) {
|
||||
|
|
@ -1145,7 +1189,7 @@ public class Tethering {
|
|||
return TETHER_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
void untetherAll() {
|
||||
void stopAllTethering() {
|
||||
stopTethering(TETHERING_WIFI);
|
||||
stopTethering(TETHERING_WIFI_P2P);
|
||||
stopTethering(TETHERING_USB);
|
||||
|
|
@ -1315,7 +1359,7 @@ public class Tethering {
|
|||
mLog.log("OBSERVED data saver changed");
|
||||
handleDataSaverChanged();
|
||||
} else if (action.equals(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING)) {
|
||||
untetherAll();
|
||||
stopAllTethering();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1479,7 +1523,7 @@ public class Tethering {
|
|||
|
||||
mDataSaverEnabled = isDataSaverEnabled;
|
||||
if (mDataSaverEnabled) {
|
||||
untetherAll();
|
||||
stopAllTethering();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1538,7 +1582,7 @@ public class Tethering {
|
|||
mNotificationUpdater.notifyTetheringDisabledByRestriction();
|
||||
|
||||
// Untether from all downstreams since tethering is disallowed.
|
||||
mTethering.untetherAll();
|
||||
mTethering.stopAllTethering();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1553,7 +1597,7 @@ public class Tethering {
|
|||
private void enableIpServing(int tetheringType, String ifname, int ipServingMode,
|
||||
boolean isNcm) {
|
||||
ensureIpServerStarted(ifname, tetheringType, isNcm);
|
||||
if (tether(ifname, ipServingMode) != TETHER_ERROR_NO_ERROR) {
|
||||
if (tetherInternal(ifname, ipServingMode) != TETHER_ERROR_NO_ERROR) {
|
||||
Log.e(TAG, "unable start tethering on iface " + ifname);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ public class TetheringService extends Service {
|
|||
IIntResultListener listener) {
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
||||
|
||||
mTethering.tether(iface, IpServer.STATE_TETHERED, listener);
|
||||
mTethering.legacyTether(iface, IpServer.STATE_TETHERED, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -119,7 +119,7 @@ public class TetheringService extends Service {
|
|||
IIntResultListener listener) {
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
||||
|
||||
mTethering.untether(iface, listener);
|
||||
mTethering.legacyUntether(iface, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -200,7 +200,7 @@ public class TetheringService extends Service {
|
|||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
||||
|
||||
try {
|
||||
mTethering.untetherAll();
|
||||
mTethering.stopAllTethering();
|
||||
listener.onResult(TETHER_ERROR_NO_ERROR);
|
||||
} catch (RemoteException e) { }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ public final class TetheringServiceTest {
|
|||
mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering).isTetheringSupported();
|
||||
verify(mTethering).isTetheringAllowed();
|
||||
verify(mTethering).tether(TEST_IFACE_NAME, IpServer.STATE_TETHERED, result);
|
||||
verify(mTethering).legacyTether(TEST_IFACE_NAME, IpServer.STATE_TETHERED, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -267,7 +267,7 @@ public final class TetheringServiceTest {
|
|||
result);
|
||||
verify(mTethering).isTetheringSupported();
|
||||
verify(mTethering).isTetheringAllowed();
|
||||
verify(mTethering).untether(eq(TEST_IFACE_NAME), eq(result));
|
||||
verify(mTethering).legacyUntether(eq(TEST_IFACE_NAME), eq(result));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -661,7 +661,7 @@ public final class TetheringServiceTest {
|
|||
mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering).isTetheringSupported();
|
||||
verify(mTethering).isTetheringAllowed();
|
||||
verify(mTethering).untetherAll();
|
||||
verify(mTethering).stopAllTethering();
|
||||
result.assertResult(TETHER_ERROR_NO_ERROR);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2098,7 +2098,7 @@ public class TetheringTest {
|
|||
|
||||
verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification))
|
||||
.notifyTetheringDisabledByRestriction();
|
||||
verify(mockTethering, times(expectedInteractionsWithShowNotification)).untetherAll();
|
||||
verify(mockTethering, times(expectedInteractionsWithShowNotification)).stopAllTethering();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -3426,7 +3426,7 @@ public class TetheringTest {
|
|||
mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false);
|
||||
mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true);
|
||||
final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
|
||||
mTethering.tether(TEST_BT_IFNAME, IpServer.STATE_TETHERED, tetherResult);
|
||||
mTethering.legacyTether(TEST_BT_IFNAME, IpServer.STATE_TETHERED, tetherResult);
|
||||
mLooper.dispatchAll();
|
||||
tetherResult.assertHasResult();
|
||||
|
||||
|
|
@ -3446,7 +3446,7 @@ public class TetheringTest {
|
|||
mTethering.stopTethering(TETHERING_BLUETOOTH);
|
||||
mLooper.dispatchAll();
|
||||
final ResultListener untetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
|
||||
mTethering.untether(TEST_BT_IFNAME, untetherResult);
|
||||
mTethering.legacyUntether(TEST_BT_IFNAME, untetherResult);
|
||||
mLooper.dispatchAll();
|
||||
untetherResult.assertHasResult();
|
||||
verifySetBluetoothTethering(false /* enable */, false /* bindToPanService */);
|
||||
|
|
@ -3476,7 +3476,7 @@ public class TetheringTest {
|
|||
mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false);
|
||||
mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true);
|
||||
final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
|
||||
mTethering.tether(TEST_BT_IFNAME, IpServer.STATE_TETHERED, tetherResult);
|
||||
mTethering.legacyTether(TEST_BT_IFNAME, IpServer.STATE_TETHERED, tetherResult);
|
||||
mLooper.dispatchAll();
|
||||
tetherResult.assertHasResult();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue