Add methods to distinguish TetheringRequest types
Add TetheringRequest#RequestType to distinguish the type of TetheringRequest (i.e. from startTethering, from implicit broadcasts, or from the legacy tether API) as well as helper methods to create these requests. These will be used in a future CL. Bug: 216524590 Test: build Change-Id: Ibfda48f59e80d423c9b6ee0d244cbdab14be1bd2
This commit is contained in:
parent
81056e4429
commit
01b9e966d8
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