Merge changes I7fae1964,Ic7cc9e1d into main
* changes: Add carrier-privileged app bypass for start/stopTethering Fix CarrierConfigRule#setHoldCarrierPrivilege race
This commit is contained in:
commit
d5743b9795
7 changed files with 419 additions and 132 deletions
|
|
@ -146,7 +146,7 @@ public class TetheringService extends Service {
|
||||||
mTethering.setUsbTethering(enable, listener);
|
mTethering.setUsbTethering(enable, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isRequestAllowedForDeviceOwner(@NonNull TetheringRequest request) {
|
private boolean isRequestAllowedForDOOrCarrierApp(@NonNull TetheringRequest request) {
|
||||||
return request.getTetheringType() == TETHERING_WIFI
|
return request.getTetheringType() == TETHERING_WIFI
|
||||||
&& request.getSoftApConfiguration() != null;
|
&& request.getSoftApConfiguration() != null;
|
||||||
}
|
}
|
||||||
|
|
@ -159,10 +159,10 @@ public class TetheringService extends Service {
|
||||||
request.setPackageName(callerPkg);
|
request.setPackageName(callerPkg);
|
||||||
boolean onlyAllowPrivileged = request.isExemptFromEntitlementCheck()
|
boolean onlyAllowPrivileged = request.isExemptFromEntitlementCheck()
|
||||||
|| request.getInterfaceName() != null;
|
|| request.getInterfaceName() != null;
|
||||||
boolean isDeviceOwnerAllowed = mTethering.isTetheringWithSoftApConfigEnabled()
|
boolean isDOOrCarrierAppAllowed = mTethering.isTetheringWithSoftApConfigEnabled()
|
||||||
&& isRequestAllowedForDeviceOwner(request);
|
&& isRequestAllowedForDOOrCarrierApp(request);
|
||||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, onlyAllowPrivileged,
|
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, onlyAllowPrivileged,
|
||||||
isDeviceOwnerAllowed, listener)) {
|
isDOOrCarrierAppAllowed, listener)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mTethering.startTethering(request, callerPkg, listener);
|
mTethering.startTethering(request, callerPkg, listener);
|
||||||
|
|
@ -191,10 +191,10 @@ public class TetheringService extends Service {
|
||||||
if (listener == null) return;
|
if (listener == null) return;
|
||||||
request.setUid(getBinderCallingUid());
|
request.setUid(getBinderCallingUid());
|
||||||
request.setPackageName(callerPkg);
|
request.setPackageName(callerPkg);
|
||||||
boolean isDeviceOwnerAllowed = mTethering.isTetheringWithSoftApConfigEnabled()
|
boolean isDOOrCarrierAppAllowed = mTethering.isTetheringWithSoftApConfigEnabled()
|
||||||
&& isRequestAllowedForDeviceOwner(request);
|
&& isRequestAllowedForDOOrCarrierApp(request);
|
||||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||||
false /* onlyAllowPrivileged */, isDeviceOwnerAllowed, listener)) {
|
false /* onlyAllowPrivileged */, isDOOrCarrierAppAllowed, listener)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Note: Whether tethering is actually stopped or not will depend on whether the request
|
// Note: Whether tethering is actually stopped or not will depend on whether the request
|
||||||
|
|
@ -274,9 +274,9 @@ public class TetheringService extends Service {
|
||||||
@Override
|
@Override
|
||||||
public void isTetheringSupported(String callerPkg, String callingAttributionTag,
|
public void isTetheringSupported(String callerPkg, String callingAttributionTag,
|
||||||
IIntResultListener listener) {
|
IIntResultListener listener) {
|
||||||
boolean isDeviceOwnerAppAllowed = mTethering.isTetheringWithSoftApConfigEnabled();
|
boolean isDOOrCarrierAppAllowed = mTethering.isTetheringWithSoftApConfigEnabled();
|
||||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||||
false /* onlyAllowPrivileged */, isDeviceOwnerAppAllowed, listener)) {
|
false /* onlyAllowPrivileged */, isDOOrCarrierAppAllowed, listener)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|
@ -304,7 +304,7 @@ public class TetheringService extends Service {
|
||||||
|
|
||||||
private boolean checkAndNotifyCommonError(final String callerPkg,
|
private boolean checkAndNotifyCommonError(final String callerPkg,
|
||||||
final String callingAttributionTag, final boolean onlyAllowPrivileged,
|
final String callingAttributionTag, final boolean onlyAllowPrivileged,
|
||||||
final boolean isDeviceOwnerAppAllowed, final IIntResultListener listener) {
|
final boolean isDOOrCarrierAppAllowed, final IIntResultListener listener) {
|
||||||
try {
|
try {
|
||||||
final int uid = getBinderCallingUid();
|
final int uid = getBinderCallingUid();
|
||||||
if (!checkPackageNameMatchesUid(uid, callerPkg)) {
|
if (!checkPackageNameMatchesUid(uid, callerPkg)) {
|
||||||
|
|
@ -313,7 +313,7 @@ public class TetheringService extends Service {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!hasTetherChangePermission(uid, callerPkg, callingAttributionTag,
|
if (!hasTetherChangePermission(uid, callerPkg, callingAttributionTag,
|
||||||
onlyAllowPrivileged, isDeviceOwnerAppAllowed)) {
|
onlyAllowPrivileged, isDOOrCarrierAppAllowed)) {
|
||||||
listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -347,14 +347,18 @@ public class TetheringService extends Service {
|
||||||
|
|
||||||
private boolean hasTetherChangePermission(final int uid, final String callerPkg,
|
private boolean hasTetherChangePermission(final int uid, final String callerPkg,
|
||||||
final String callingAttributionTag, final boolean onlyAllowPrivileged,
|
final String callingAttributionTag, final boolean onlyAllowPrivileged,
|
||||||
final boolean isDeviceOwnerAppAllowed) {
|
final boolean isDOOrCarrierAppAllowed) {
|
||||||
if (onlyAllowPrivileged && !hasNetworkStackPermission()
|
if (onlyAllowPrivileged && !hasNetworkStackPermission()
|
||||||
&& !hasNetworkSettingsPermission()) return false;
|
&& !hasNetworkSettingsPermission()) return false;
|
||||||
|
|
||||||
if (hasTetherPrivilegedPermission()) return true;
|
if (hasTetherPrivilegedPermission()) return true;
|
||||||
|
|
||||||
// Allow DO apps to change tethering even if they don't have TETHER_PRIVILEGED.
|
// Allow DO and carrier-privileged apps to change tethering even if they don't have
|
||||||
if (isDeviceOwnerAppAllowed && mService.isDeviceOwner(uid, callerPkg)) {
|
// TETHER_PRIVILEGED.
|
||||||
|
// TODO: Stop tethering if the app loses DO status or carrier-privileges.
|
||||||
|
if (isDOOrCarrierAppAllowed
|
||||||
|
&& (mService.isDeviceOwner(uid, callerPkg)
|
||||||
|
|| mService.isCarrierPrivileged(callerPkg))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -435,6 +439,14 @@ public class TetheringService extends Service {
|
||||||
return mTetheringPermissionsUtils.isDeviceOwner(uid, callerPkg);
|
return mTetheringPermissionsUtils.isDeviceOwner(uid, callerPkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for {@link TetheringPermissionsUtils#isCarrierPrivileged(String)}, used for mocks.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean isCarrierPrivileged(final String callerPkg) {
|
||||||
|
return mTetheringPermissionsUtils.isCarrierPrivileged(callerPkg);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An injection method for testing.
|
* An injection method for testing.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,9 @@ package com.android.networkstack.tethering.util;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
@ -68,4 +70,20 @@ public class TetheringPermissionsUtils {
|
||||||
}
|
}
|
||||||
return devicePolicyManager;
|
return devicePolicyManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the package name has carrier privileges.
|
||||||
|
*/
|
||||||
|
public boolean isCarrierPrivileged(@NonNull final String packageName) {
|
||||||
|
TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
|
||||||
|
if (telephonyManager == null) return false;
|
||||||
|
|
||||||
|
long ident = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
return telephonyManager.checkCarrierPrivilegesForPackageAnyPhone(packageName)
|
||||||
|
== TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ public class MockTetheringService extends TetheringService {
|
||||||
private final ArrayMap<String, Integer> mMockedPermissions = new ArrayMap<>();
|
private final ArrayMap<String, Integer> mMockedPermissions = new ArrayMap<>();
|
||||||
private final ArrayMap<String, Integer> mMockedPackageUids = new ArrayMap<>();
|
private final ArrayMap<String, Integer> mMockedPackageUids = new ArrayMap<>();
|
||||||
private final Set<String> mMockedDeviceOwnerPackages = new ArraySet<>();
|
private final Set<String> mMockedDeviceOwnerPackages = new ArraySet<>();
|
||||||
|
private final Set<String> mMockedCarrierPrivilegedPackages = new ArraySet<>();
|
||||||
private int mMockCallingUid;
|
private int mMockCallingUid;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -83,6 +84,11 @@ public class MockTetheringService extends TetheringService {
|
||||||
return mMockedDeviceOwnerPackages.contains(callerPkg);
|
return mMockedDeviceOwnerPackages.contains(callerPkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isCarrierPrivileged(final String callerPkg) {
|
||||||
|
return mMockedCarrierPrivilegedPackages.contains(callerPkg);
|
||||||
|
}
|
||||||
|
|
||||||
public Tethering getTethering() {
|
public Tethering getTethering() {
|
||||||
return mTethering;
|
return mTethering;
|
||||||
}
|
}
|
||||||
|
|
@ -141,5 +147,19 @@ public class MockTetheringService extends TetheringService {
|
||||||
public void removeDeviceOwnerPackage(final String packageName) {
|
public void removeDeviceOwnerPackage(final String packageName) {
|
||||||
mMockedDeviceOwnerPackages.remove(packageName);
|
mMockedDeviceOwnerPackages.remove(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a mocked carrier privileges package
|
||||||
|
*/
|
||||||
|
public void addCarrierPrivilegedPackage(final String packageName) {
|
||||||
|
mMockedCarrierPrivilegedPackages.add(packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a mocked carrier privileges package
|
||||||
|
*/
|
||||||
|
public void removeCarrierPrivilegedPackage(final String packageName) {
|
||||||
|
mMockedCarrierPrivilegedPackages.remove(packageName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,15 @@ public final class TetheringServiceTest {
|
||||||
private static final int TEST_CALLER_UID = 1234;
|
private static final int TEST_CALLER_UID = 1234;
|
||||||
private static final String TEST_ATTRIBUTION_TAG = null;
|
private static final String TEST_ATTRIBUTION_TAG = null;
|
||||||
private static final String TEST_WRONG_PACKAGE = "wrong.package";
|
private static final String TEST_WRONG_PACKAGE = "wrong.package";
|
||||||
|
private static final int NO_RESULT = -1;
|
||||||
|
private static final TetheringRequest USB_REQUEST =
|
||||||
|
new TetheringRequest.Builder(TETHERING_USB).build();
|
||||||
|
private static final TetheringRequest WIFI_REQUEST_NO_CONFIG =
|
||||||
|
new TetheringRequest.Builder(TETHERING_WIFI).build();
|
||||||
|
private static final TetheringRequest WIFI_REQUEST_WITH_CONFIG =
|
||||||
|
new TetheringRequest.Builder(TETHERING_WIFI)
|
||||||
|
.setSoftApConfiguration(new SoftApConfiguration.Builder().build())
|
||||||
|
.build();
|
||||||
@Mock private ITetheringEventCallback mITetheringEventCallback;
|
@Mock private ITetheringEventCallback mITetheringEventCallback;
|
||||||
@Rule public ServiceTestRule mServiceTestRule;
|
@Rule public ServiceTestRule mServiceTestRule;
|
||||||
private Tethering mTethering;
|
private Tethering mTethering;
|
||||||
|
|
@ -100,7 +109,7 @@ public final class TetheringServiceTest {
|
||||||
@Mock private AppOpsManager mAppOps;
|
@Mock private AppOpsManager mAppOps;
|
||||||
|
|
||||||
private class TestTetheringResult extends IIntResultListener.Stub {
|
private class TestTetheringResult extends IIntResultListener.Stub {
|
||||||
private int mResult = -1; // Default value that does not match any result code.
|
private int mResult = NO_RESULT;
|
||||||
@Override
|
@Override
|
||||||
public void onResult(final int resultCode) {
|
public void onResult(final int resultCode) {
|
||||||
mResult = resultCode;
|
mResult = resultCode;
|
||||||
|
|
@ -115,7 +124,7 @@ public final class TetheringServiceTest {
|
||||||
MyResultReceiver(Handler handler) {
|
MyResultReceiver(Handler handler) {
|
||||||
super(handler);
|
super(handler);
|
||||||
}
|
}
|
||||||
private int mResult = -1; // Default value that does not match any result code.
|
private int mResult = NO_RESULT;
|
||||||
@Override
|
@Override
|
||||||
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||||
mResult = resultCode;
|
mResult = resultCode;
|
||||||
|
|
@ -206,6 +215,21 @@ public final class TetheringServiceTest {
|
||||||
mMockConnector.removeDeviceOwnerPackage(TEST_CALLER_PKG);
|
mMockConnector.removeDeviceOwnerPackage(TEST_CALLER_PKG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void runAsCarrierPrivileged(final TestTetheringCall test) throws Exception {
|
||||||
|
mMockConnector.addCarrierPrivilegedPackage(TEST_CALLER_PKG);
|
||||||
|
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||||
|
true /* isTetheringWithSoftApConfigEnabled */, new String[0]);
|
||||||
|
mMockConnector.removeCarrierPrivilegedPackage(TEST_CALLER_PKG);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runAsCarrierPrivilegedWhenCarrierPrivilegeBypassNotEnabled(
|
||||||
|
final TestTetheringCall test) throws Exception {
|
||||||
|
mMockConnector.addCarrierPrivilegedPackage(TEST_CALLER_PKG);
|
||||||
|
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||||
|
false /* isTetheringWithSoftApConfigEnabled */, new String[0]);
|
||||||
|
mMockConnector.removeCarrierPrivilegedPackage(TEST_CALLER_PKG);
|
||||||
|
}
|
||||||
|
|
||||||
private void runTetheringCall(final TestTetheringCall test, boolean isTetheringAllowed,
|
private void runTetheringCall(final TestTetheringCall test, boolean isTetheringAllowed,
|
||||||
boolean isTetheringWithSoftApConfigEnabled, String... permissions) throws Exception {
|
boolean isTetheringWithSoftApConfigEnabled, String... permissions) throws Exception {
|
||||||
// Allow the test to run even if ACCESS_NETWORK_STATE was granted at the APK level
|
// Allow the test to run even if ACCESS_NETWORK_STATE was granted at the APK level
|
||||||
|
|
@ -381,125 +405,114 @@ public final class TetheringServiceTest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runStartTethering(final TestTetheringResult result,
|
private void verifyStartTetheringRequestSucceeds(final TetheringRequest request,
|
||||||
final TetheringRequestParcel request) throws Exception {
|
final TestTetheringResult result) throws Exception {
|
||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.startTethering(request.getParcel(), TEST_CALLER_PKG,
|
||||||
result);
|
TEST_ATTRIBUTION_TAG, result);
|
||||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering).startTethering(eq(request), eq(TEST_CALLER_PKG), eq(result));
|
||||||
verify(mTethering).isTetheringSupported();
|
reset(mTethering);
|
||||||
verify(mTethering).isTetheringAllowed();
|
result.assertResult(NO_RESULT);
|
||||||
verify(mTethering).startTethering(
|
}
|
||||||
eq(new TetheringRequest(request)), eq(TEST_CALLER_PKG), eq(result));
|
|
||||||
|
private void verifyStartTetheringRequestFails(final TetheringRequest request,
|
||||||
|
final TestTetheringResult result, final int resultCode) throws Exception {
|
||||||
|
mTetheringConnector.startTethering(request.getParcel(), TEST_CALLER_PKG,
|
||||||
|
TEST_ATTRIBUTION_TAG, result);
|
||||||
|
verify(mTethering, never()).startTethering(any(), any(), any());
|
||||||
|
reset(mTethering);
|
||||||
|
result.assertResult(resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyStartTetheringRequestWithWrongPackageFails(final TetheringRequest request,
|
||||||
|
final TestTetheringResult result) throws Exception {
|
||||||
|
mTetheringConnector.startTethering(request.getParcel(), TEST_WRONG_PACKAGE,
|
||||||
|
TEST_ATTRIBUTION_TAG, result);
|
||||||
|
verify(mTethering, never()).startTethering(any(), any(), any());
|
||||||
|
reset(mTethering);
|
||||||
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartTethering() throws Exception {
|
public void testStartTethering() throws Exception {
|
||||||
final TetheringRequestParcel request = new TetheringRequestParcel();
|
|
||||||
request.tetheringType = TETHERING_WIFI;
|
|
||||||
|
|
||||||
runAsNoPermission((result) -> {
|
runAsNoPermission((result) -> {
|
||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
verifyStartTetheringRequestFails(WIFI_REQUEST_NO_CONFIG, result,
|
||||||
result);
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
|
||||||
verifyNoMoreInteractionsForTethering();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Not a Wifi request - Fail
|
|
||||||
runAsDeviceOwner((result) -> {
|
|
||||||
final TetheringRequestParcel notWifi = new TetheringRequestParcel();
|
|
||||||
notWifi.tetheringType = TETHERING_USB;
|
|
||||||
mTetheringConnector.startTethering(notWifi, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
|
||||||
result);
|
|
||||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
|
||||||
verifyNoMoreInteractionsForTethering();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Request has no SoftApConfiguration - Fail
|
|
||||||
runAsDeviceOwner((result) -> {
|
|
||||||
final TetheringRequestParcel noConfig = new TetheringRequestParcel();
|
|
||||||
noConfig.tetheringType = TETHERING_WIFI;
|
|
||||||
mTetheringConnector.startTethering(noConfig, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
|
||||||
result);
|
|
||||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
|
||||||
verifyNoMoreInteractionsForTethering();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wifi request with SoftApConfiguration - Succeed
|
|
||||||
runAsDeviceOwner((result) -> {
|
|
||||||
final TetheringRequestParcel withConfig = new TetheringRequestParcel();
|
|
||||||
withConfig.tetheringType = TETHERING_WIFI;
|
|
||||||
withConfig.softApConfig = new SoftApConfiguration.Builder().build();
|
|
||||||
mTetheringConnector.startTethering(withConfig, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
|
||||||
result);
|
|
||||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
|
||||||
verify(mTethering).isTetheringSupported();
|
|
||||||
verify(mTethering).isTetheringAllowed();
|
|
||||||
verify(mTethering).startTethering(any(), any(), any());
|
|
||||||
result.assertResult(-1); // No result
|
|
||||||
verifyNoMoreInteractionsForTethering();
|
|
||||||
});
|
|
||||||
|
|
||||||
runAsDeviceOwnerWhenDeviceOwnerBypassNotEnabled((result) -> {
|
|
||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
|
||||||
result);
|
|
||||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
|
||||||
verify(mTethering).isTetherProvisioningRequired();
|
|
||||||
verifyNoMoreInteractionsForTethering();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsTetherPrivileged((result) -> {
|
runAsTetherPrivileged((result) -> {
|
||||||
mTetheringConnector.startTethering(request, TEST_WRONG_PACKAGE,
|
verifyStartTetheringRequestSucceeds(WIFI_REQUEST_NO_CONFIG, result);
|
||||||
TEST_ATTRIBUTION_TAG, result);
|
|
||||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
|
||||||
verify(mTethering, never()).startTethering(
|
|
||||||
eq(new TetheringRequest(request)), eq(TEST_WRONG_PACKAGE), eq(result));
|
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
|
||||||
verifyNoMoreInteractionsForTethering();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsTetherPrivileged((result) -> {
|
runAsTetherPrivileged((result) -> {
|
||||||
runStartTethering(result, request);
|
verifyStartTetheringRequestWithWrongPackageFails(WIFI_REQUEST_NO_CONFIG, result);
|
||||||
verifyNoMoreInteractionsForTethering();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettings((result) -> {
|
runAsWriteSettings((result) -> {
|
||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
verifyStartTetheringRequestFails(WIFI_REQUEST_NO_CONFIG, result,
|
||||||
result);
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
|
||||||
verifyNoMoreInteractionsForTethering();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||||
runStartTethering(result, request);
|
verifyStartTetheringRequestSucceeds(WIFI_REQUEST_NO_CONFIG, result);
|
||||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
|
||||||
verify(mTethering).isTetherProvisioningRequired();
|
|
||||||
verifyNoMoreInteractionsForTethering();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsTetheringDisallowed((result) -> {
|
runAsTetheringDisallowed((result) -> {
|
||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
verifyStartTetheringRequestFails(WIFI_REQUEST_NO_CONFIG, result,
|
||||||
result);
|
TETHER_ERROR_UNSUPPORTED);
|
||||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
});
|
||||||
verify(mTethering).isTetheringSupported();
|
|
||||||
verify(mTethering).isTetheringAllowed();
|
// Not wifi -> fail
|
||||||
result.assertResult(TETHER_ERROR_UNSUPPORTED);
|
runAsDeviceOwner((result) -> {
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyStartTetheringRequestFails(USB_REQUEST, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
});
|
||||||
|
|
||||||
|
// No SoftApConfiguration -> fail
|
||||||
|
runAsDeviceOwner((result) -> {
|
||||||
|
verifyStartTetheringRequestFails(WIFI_REQUEST_NO_CONFIG, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
});
|
||||||
|
|
||||||
|
// With SoftApConfiguration -> success
|
||||||
|
runAsDeviceOwner((result) -> {
|
||||||
|
verifyStartTetheringRequestSucceeds(WIFI_REQUEST_WITH_CONFIG, result);
|
||||||
|
});
|
||||||
|
|
||||||
|
runAsDeviceOwnerWhenDeviceOwnerBypassNotEnabled((result) -> {
|
||||||
|
verifyStartTetheringRequestFails(WIFI_REQUEST_WITH_CONFIG, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Not wifi -> fail
|
||||||
|
runAsCarrierPrivileged((result) -> {
|
||||||
|
verifyStartTetheringRequestFails(USB_REQUEST, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
});
|
||||||
|
|
||||||
|
// No SoftApConfiguration -> fail
|
||||||
|
runAsCarrierPrivileged((result) -> {
|
||||||
|
verifyStartTetheringRequestFails(WIFI_REQUEST_NO_CONFIG, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
});
|
||||||
|
|
||||||
|
// With SoftApConfiguration -> success
|
||||||
|
runAsCarrierPrivileged((result) -> {
|
||||||
|
verifyStartTetheringRequestSucceeds(WIFI_REQUEST_WITH_CONFIG, result);
|
||||||
|
});
|
||||||
|
|
||||||
|
runAsCarrierPrivilegedWhenCarrierPrivilegeBypassNotEnabled((result) -> {
|
||||||
|
verifyStartTetheringRequestFails(WIFI_REQUEST_WITH_CONFIG, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartTetheringWithInterfaceSucceeds() throws Exception {
|
public void testStartTetheringWithInterfaceSucceeds() throws Exception {
|
||||||
final TetheringRequestParcel request = new TetheringRequestParcel();
|
final TetheringRequest request = new TetheringRequest.Builder(TETHERING_VIRTUAL)
|
||||||
request.tetheringType = TETHERING_VIRTUAL;
|
.setInterfaceName("avf_tap_fixed")
|
||||||
request.interfaceName = "avf_tap_fixed";
|
.build();
|
||||||
|
|
||||||
runAsNetworkSettings((result) -> {
|
runAsNetworkSettings((result) -> {
|
||||||
runStartTethering(result, request);
|
verifyStartTetheringRequestSucceeds(request, result);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -599,84 +612,110 @@ public final class TetheringServiceTest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyHasPermissionForStopTetheringRequest(TetheringRequest request,
|
private void verifyStopTetheringRequestSucceeds(final TetheringRequest request,
|
||||||
final TestTetheringResult result) throws Exception {
|
final TestTetheringResult result) throws Exception {
|
||||||
mTetheringConnector.stopTetheringRequest(request, TEST_CALLER_PKG,
|
mTetheringConnector.stopTetheringRequest(request, TEST_CALLER_PKG,
|
||||||
TEST_ATTRIBUTION_TAG, result);
|
TEST_ATTRIBUTION_TAG, result);
|
||||||
verify(mTethering).stopTetheringRequest(any(), any());
|
verify(mTethering).stopTetheringRequest(any(), any());
|
||||||
verify(mTethering).isTetheringSupported();
|
|
||||||
verify(mTethering).isTetheringAllowed();
|
|
||||||
reset(mTethering);
|
reset(mTethering);
|
||||||
|
result.assertResult(NO_RESULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyDoesNotHavePermissionForStopTetheringRequest(TetheringRequest request,
|
private void verifyStopTetheringRequestFails(final TetheringRequest request,
|
||||||
final TestTetheringResult result) throws Exception {
|
final TestTetheringResult result, int resultCode) throws Exception {
|
||||||
mTetheringConnector.stopTetheringRequest(request, TEST_CALLER_PKG,
|
mTetheringConnector.stopTetheringRequest(request, TEST_CALLER_PKG,
|
||||||
TEST_ATTRIBUTION_TAG, result);
|
TEST_ATTRIBUTION_TAG, result);
|
||||||
verify(mTethering, never()).stopTetheringRequest(any(), any());
|
verify(mTethering, never()).stopTetheringRequest(any(), any());
|
||||||
|
reset(mTethering);
|
||||||
|
result.assertResult(resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyStopTetheringRequestWithWrongPackageFails(final TetheringRequest request,
|
||||||
|
final TestTetheringResult result) throws Exception {
|
||||||
|
mTetheringConnector.stopTetheringRequest(request, TEST_WRONG_PACKAGE,
|
||||||
|
TEST_ATTRIBUTION_TAG, result);
|
||||||
|
verify(mTethering, never()).stopTetheringRequest(any(), any());
|
||||||
|
reset(mTethering);
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
reset(mTethering);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyStopTetheringRequestWithTetheringDisallowed(TetheringRequest request,
|
|
||||||
final TestTetheringResult result) throws Exception {
|
|
||||||
mTetheringConnector.stopTetheringRequest(request, TEST_CALLER_PKG,
|
|
||||||
TEST_ATTRIBUTION_TAG, result);
|
|
||||||
verify(mTethering, never()).stopTetheringRequest(any(), any());
|
|
||||||
result.assertResult(TETHER_ERROR_UNSUPPORTED);
|
|
||||||
reset(mTethering);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStopTetheringRequest() throws Exception {
|
public void testStopTetheringRequest() throws Exception {
|
||||||
TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI).build();
|
|
||||||
|
|
||||||
runAsNoPermission((result) -> {
|
runAsNoPermission((result) -> {
|
||||||
verifyDoesNotHavePermissionForStopTetheringRequest(request, result);
|
verifyStopTetheringRequestFails(WIFI_REQUEST_NO_CONFIG, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsTetherPrivileged((result) -> {
|
runAsTetherPrivileged((result) -> {
|
||||||
verifyHasPermissionForStopTetheringRequest(request, result);
|
verifyStopTetheringRequestSucceeds(WIFI_REQUEST_NO_CONFIG, result);
|
||||||
|
});
|
||||||
|
|
||||||
|
runAsTetherPrivileged((result) -> {
|
||||||
|
verifyStopTetheringRequestWithWrongPackageFails(WIFI_REQUEST_NO_CONFIG, result);
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettings((result) -> {
|
runAsWriteSettings((result) -> {
|
||||||
verifyDoesNotHavePermissionForStopTetheringRequest(request, result);
|
verifyStopTetheringRequestFails(WIFI_REQUEST_NO_CONFIG, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||||
verifyHasPermissionForStopTetheringRequest(request, result);
|
// Note: This can't happen in practice since WRITE_SETTINGS is only allowed on V- and
|
||||||
|
// stopTetheringRequest is only allowed on B+, but we test here for completeness.
|
||||||
|
verifyStopTetheringRequestSucceeds(WIFI_REQUEST_NO_CONFIG, result);
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsTetheringDisallowed((result) -> {
|
runAsTetheringDisallowed((result) -> {
|
||||||
verifyStopTetheringRequestWithTetheringDisallowed(request, result);
|
verifyStopTetheringRequestFails(WIFI_REQUEST_NO_CONFIG, result,
|
||||||
|
TETHER_ERROR_UNSUPPORTED);
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsNetworkSettings((result) -> {
|
runAsNetworkSettings((result) -> {
|
||||||
verifyHasPermissionForStopTetheringRequest(request, result);
|
verifyStopTetheringRequestSucceeds(WIFI_REQUEST_NO_CONFIG, result);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Not wifi -> fail
|
// Not wifi -> fail
|
||||||
runAsDeviceOwner((result) -> {
|
runAsDeviceOwner((result) -> {
|
||||||
TetheringRequest notWifi = new TetheringRequest.Builder(TETHERING_USB).build();
|
verifyStopTetheringRequestFails(USB_REQUEST, result,
|
||||||
verifyDoesNotHavePermissionForStopTetheringRequest(notWifi, result);
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
});
|
});
|
||||||
|
|
||||||
// No config -> fail
|
// No SoftApConfiguration -> fail
|
||||||
runAsDeviceOwner((result) -> {
|
runAsDeviceOwner((result) -> {
|
||||||
TetheringRequest noConfig = new TetheringRequest.Builder(TETHERING_WIFI).build();
|
verifyStopTetheringRequestFails(WIFI_REQUEST_NO_CONFIG, result,
|
||||||
verifyDoesNotHavePermissionForStopTetheringRequest(noConfig, result);
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
});
|
});
|
||||||
|
|
||||||
// With config -> success
|
// With SoftApConfiguration -> success
|
||||||
TetheringRequest withConfig = new TetheringRequest.Builder(TETHERING_WIFI)
|
|
||||||
.setSoftApConfiguration(new SoftApConfiguration.Builder().build())
|
|
||||||
.build();
|
|
||||||
runAsDeviceOwner((result) -> {
|
runAsDeviceOwner((result) -> {
|
||||||
verifyHasPermissionForStopTetheringRequest(withConfig, result);
|
verifyStopTetheringRequestSucceeds(WIFI_REQUEST_WITH_CONFIG, result);
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsDeviceOwnerWhenDeviceOwnerBypassNotEnabled((result) -> {
|
runAsDeviceOwnerWhenDeviceOwnerBypassNotEnabled((result) -> {
|
||||||
verifyDoesNotHavePermissionForStopTetheringRequest(withConfig, result);
|
verifyStopTetheringRequestFails(WIFI_REQUEST_WITH_CONFIG, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Not wifi -> fail
|
||||||
|
runAsCarrierPrivileged((result) -> {
|
||||||
|
verifyStopTetheringRequestFails(USB_REQUEST, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
});
|
||||||
|
|
||||||
|
// No SoftApConfiguration -> fail
|
||||||
|
runAsCarrierPrivileged((result) -> {
|
||||||
|
verifyStopTetheringRequestFails(WIFI_REQUEST_NO_CONFIG, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
});
|
||||||
|
|
||||||
|
// With SoftApConfiguration -> success
|
||||||
|
runAsCarrierPrivileged((result) -> {
|
||||||
|
verifyStopTetheringRequestSucceeds(WIFI_REQUEST_WITH_CONFIG, result);
|
||||||
|
});
|
||||||
|
|
||||||
|
runAsCarrierPrivilegedWhenCarrierPrivilegeBypassNotEnabled((result) -> {
|
||||||
|
verifyStopTetheringRequestFails(WIFI_REQUEST_WITH_CONFIG, result,
|
||||||
|
TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,4 +67,15 @@ public class TetheringPermissionsUtilsTest {
|
||||||
when(mDevicePolicyManager.isDeviceOwnerApp(TEST_PACKAGE)).thenReturn(true);
|
when(mDevicePolicyManager.isDeviceOwnerApp(TEST_PACKAGE)).thenReturn(true);
|
||||||
assertThat(mTetheringPermissionsUtils.isDeviceOwner(TEST_UID, TEST_PACKAGE)).isTrue();
|
assertThat(mTetheringPermissionsUtils.isDeviceOwner(TEST_UID, TEST_PACKAGE)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHasCarrierPrivilege() {
|
||||||
|
when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(TEST_PACKAGE))
|
||||||
|
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
|
||||||
|
assertThat(mTetheringPermissionsUtils.isCarrierPrivileged(TEST_PACKAGE)).isFalse();
|
||||||
|
|
||||||
|
when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(TEST_PACKAGE))
|
||||||
|
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
|
||||||
|
assertThat(mTetheringPermissionsUtils.isCarrierPrivileged(TEST_PACKAGE)).isTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ import com.android.modules.utils.build.SdkLevel
|
||||||
import com.android.testutils.runAsShell
|
import com.android.testutils.runAsShell
|
||||||
import com.android.testutils.tryTest
|
import com.android.testutils.tryTest
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
import org.junit.rules.TestRule
|
import org.junit.rules.TestRule
|
||||||
|
|
@ -204,6 +205,7 @@ class CarrierConfigRule : TestRule {
|
||||||
}
|
}
|
||||||
return@tryTest
|
return@tryTest
|
||||||
}
|
}
|
||||||
|
cv.close()
|
||||||
if (hold) {
|
if (hold) {
|
||||||
addConfigOverrides(subId, PersistableBundle().also {
|
addConfigOverrides(subId, PersistableBundle().also {
|
||||||
it.putStringArray(CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY,
|
it.putStringArray(CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY,
|
||||||
|
|
@ -212,6 +214,9 @@ class CarrierConfigRule : TestRule {
|
||||||
} else {
|
} else {
|
||||||
cleanUpNow()
|
cleanUpNow()
|
||||||
}
|
}
|
||||||
|
assertTrue(cv.block(CARRIER_CONFIG_CHANGE_TIMEOUT_MS),
|
||||||
|
"Timed out waiting for CarrierPrivilegesCallback")
|
||||||
|
assertEquals(cpb.hasPrivilege, hold, "Couldn't set carrier privilege")
|
||||||
} cleanup @JvmSerializableLambda {
|
} cleanup @JvmSerializableLambda {
|
||||||
runAsShell(READ_PRIVILEGED_PHONE_STATE) @JvmSerializableLambda {
|
runAsShell(READ_PRIVILEGED_PHONE_STATE) @JvmSerializableLambda {
|
||||||
tm.unregisterCarrierPrivilegesCallback(cpb)
|
tm.unregisterCarrierPrivilegesCallback(cpb)
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import static android.net.TetheringManager.TETHER_ERROR_DUPLICATE_REQUEST;
|
||||||
import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
|
import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
|
||||||
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
|
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
|
||||||
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
||||||
|
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_REQUEST;
|
||||||
import static android.net.cts.util.CtsTetheringUtils.isAnyIfaceMatch;
|
import static android.net.cts.util.CtsTetheringUtils.isAnyIfaceMatch;
|
||||||
import static android.os.Process.INVALID_UID;
|
import static android.os.Process.INVALID_UID;
|
||||||
|
|
||||||
|
|
@ -714,4 +715,185 @@ public class TetheringManagerTest {
|
||||||
assertThrows(UnsupportedOperationException.class, () -> mTM.tether("iface"));
|
assertThrows(UnsupportedOperationException.class, () -> mTM.tether("iface"));
|
||||||
assertThrows(UnsupportedOperationException.class, () -> mTM.untether("iface"));
|
assertThrows(UnsupportedOperationException.class, () -> mTM.untether("iface"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCarrierPrivilegedIsTetheringSupported() throws Exception {
|
||||||
|
assumeTrue(SdkLevel.isAtLeastB());
|
||||||
|
assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
|
||||||
|
int defaultSubId = SubscriptionManager.getDefaultSubscriptionId();
|
||||||
|
mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId);
|
||||||
|
final TestTetheringEventCallback tetherEventCallback =
|
||||||
|
mCtsTetheringUtils.registerTetheringEventCallback();
|
||||||
|
try {
|
||||||
|
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
||||||
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
|
|
||||||
|
assertTrue(mTM.isTetheringSupported());
|
||||||
|
} finally {
|
||||||
|
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCarrierPrivilegedStartTetheringNonWifiFails() throws Exception {
|
||||||
|
assumeTrue(SdkLevel.isAtLeastB());
|
||||||
|
assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
|
||||||
|
int defaultSubId = SubscriptionManager.getDefaultSubscriptionId();
|
||||||
|
mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId);
|
||||||
|
final TestTetheringEventCallback tetherEventCallback =
|
||||||
|
mCtsTetheringUtils.registerTetheringEventCallback();
|
||||||
|
try {
|
||||||
|
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
||||||
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
|
StartTetheringCallback callback = new StartTetheringCallback();
|
||||||
|
TetheringRequest request = new TetheringRequest.Builder(TETHERING_USB).build();
|
||||||
|
|
||||||
|
mTM.startTethering(request, Runnable::run, callback);
|
||||||
|
|
||||||
|
callback.expectTetheringFailed(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
} finally {
|
||||||
|
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCarrierPrivilegedStartTetheringWifiWithoutConfigFails() throws Exception {
|
||||||
|
assumeTrue(SdkLevel.isAtLeastB());
|
||||||
|
assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
|
||||||
|
int defaultSubId = SubscriptionManager.getDefaultSubscriptionId();
|
||||||
|
mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId);
|
||||||
|
final TestTetheringEventCallback tetherEventCallback =
|
||||||
|
mCtsTetheringUtils.registerTetheringEventCallback();
|
||||||
|
try {
|
||||||
|
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
||||||
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
|
StartTetheringCallback callback = new StartTetheringCallback();
|
||||||
|
TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI).build();
|
||||||
|
|
||||||
|
mTM.startTethering(request, Runnable::run, callback);
|
||||||
|
|
||||||
|
callback.expectTetheringFailed(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
} finally {
|
||||||
|
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCarrierPrivilegedStartTetheringWifiWithConfigSucceeds() throws Exception {
|
||||||
|
assumeTrue(SdkLevel.isAtLeastB());
|
||||||
|
assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
|
||||||
|
int defaultSubId = SubscriptionManager.getDefaultSubscriptionId();
|
||||||
|
mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId);
|
||||||
|
final TestTetheringEventCallback tetherEventCallback =
|
||||||
|
mCtsTetheringUtils.registerTetheringEventCallback();
|
||||||
|
try {
|
||||||
|
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
||||||
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
|
SoftApConfiguration softApConfig = createSoftApConfiguration("Carrier-privileged");
|
||||||
|
|
||||||
|
mCtsTetheringUtils.startWifiTetheringNoPermissions(tetherEventCallback, softApConfig);
|
||||||
|
} finally {
|
||||||
|
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCarrierPrivilegedStopTetheringNonWifiFails() throws Exception {
|
||||||
|
assumeTrue(SdkLevel.isAtLeastB());
|
||||||
|
assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
|
||||||
|
int defaultSubId = SubscriptionManager.getDefaultSubscriptionId();
|
||||||
|
mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId);
|
||||||
|
final TestTetheringEventCallback tetherEventCallback =
|
||||||
|
mCtsTetheringUtils.registerTetheringEventCallback();
|
||||||
|
try {
|
||||||
|
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
||||||
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
|
TetheringRequest request = new TetheringRequest.Builder(TETHERING_USB).build();
|
||||||
|
CtsTetheringUtils.StopTetheringCallback
|
||||||
|
callback = new CtsTetheringUtils.StopTetheringCallback();
|
||||||
|
|
||||||
|
mTM.stopTethering(request, Runnable::run, callback);
|
||||||
|
|
||||||
|
callback.expectStopTetheringFailed(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
} finally {
|
||||||
|
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCarrierPrivilegedStopTetheringWifiWithoutConfigFails() throws Exception {
|
||||||
|
assumeTrue(SdkLevel.isAtLeastB());
|
||||||
|
assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
|
||||||
|
int defaultSubId = SubscriptionManager.getDefaultSubscriptionId();
|
||||||
|
mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId);
|
||||||
|
final TestTetheringEventCallback tetherEventCallback =
|
||||||
|
mCtsTetheringUtils.registerTetheringEventCallback();
|
||||||
|
try {
|
||||||
|
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
||||||
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
|
TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI).build();
|
||||||
|
CtsTetheringUtils.StopTetheringCallback
|
||||||
|
callback = new CtsTetheringUtils.StopTetheringCallback();
|
||||||
|
|
||||||
|
mTM.stopTethering(request, Runnable::run, callback);
|
||||||
|
|
||||||
|
callback.expectStopTetheringFailed(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
} finally {
|
||||||
|
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCarrierPrivilegedStopTetheringWifiWithConfigButNoActiveRequestFails()
|
||||||
|
throws Exception {
|
||||||
|
assumeTrue(SdkLevel.isAtLeastB());
|
||||||
|
assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
|
||||||
|
int defaultSubId = SubscriptionManager.getDefaultSubscriptionId();
|
||||||
|
mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId);
|
||||||
|
final TestTetheringEventCallback tetherEventCallback =
|
||||||
|
mCtsTetheringUtils.registerTetheringEventCallback();
|
||||||
|
try {
|
||||||
|
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
||||||
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
|
SoftApConfiguration softApConfig = createSoftApConfiguration("Carrier-privileged");
|
||||||
|
TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
|
||||||
|
.setSoftApConfiguration(softApConfig)
|
||||||
|
.build();
|
||||||
|
CtsTetheringUtils.StopTetheringCallback
|
||||||
|
callback = new CtsTetheringUtils.StopTetheringCallback();
|
||||||
|
|
||||||
|
mTM.stopTethering(request, Runnable::run, callback);
|
||||||
|
|
||||||
|
callback.expectStopTetheringFailed(TETHER_ERROR_UNKNOWN_REQUEST);
|
||||||
|
} finally {
|
||||||
|
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCarrierPrivilegedStopTetheringWifiWithConfigSucceeds() throws Exception {
|
||||||
|
assumeTrue(SdkLevel.isAtLeastB());
|
||||||
|
assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
|
||||||
|
int defaultSubId = SubscriptionManager.getDefaultSubscriptionId();
|
||||||
|
mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId);
|
||||||
|
final TestTetheringEventCallback tetherEventCallback =
|
||||||
|
mCtsTetheringUtils.registerTetheringEventCallback();
|
||||||
|
try {
|
||||||
|
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
||||||
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
|
SoftApConfiguration softApConfig = createSoftApConfiguration("Carrier-privileged");
|
||||||
|
mCtsTetheringUtils.startWifiTetheringNoPermissions(tetherEventCallback, softApConfig);
|
||||||
|
TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
|
||||||
|
.setSoftApConfiguration(softApConfig)
|
||||||
|
.build();
|
||||||
|
CtsTetheringUtils.StopTetheringCallback
|
||||||
|
callback = new CtsTetheringUtils.StopTetheringCallback();
|
||||||
|
|
||||||
|
mTM.stopTethering(request, Runnable::run, callback);
|
||||||
|
|
||||||
|
callback.verifyStopTetheringSucceeded();
|
||||||
|
} finally {
|
||||||
|
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue