TetheringServiceTest: test caller permission
Bug: 154869719
Test: atest TetheringTests
Change-Id: I7beea3f011d930e433443ed62d772a3f8cce5d78
diff --git a/Tethering/tests/unit/AndroidManifest.xml b/Tethering/tests/unit/AndroidManifest.xml
index 31eaabf..355342f 100644
--- a/Tethering/tests/unit/AndroidManifest.xml
+++ b/Tethering/tests/unit/AndroidManifest.xml
@@ -16,9 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.networkstack.tethering.tests.unit">
- <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <uses-permission android:name="android.permission.TETHER_PRIVILEGED"/>
-
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<service
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
index 3dc6a13..cf060ba 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
@@ -16,20 +16,29 @@
package com.android.networkstack.tethering;
+import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.Manifest.permission.TETHER_PRIVILEGED;
+import static android.Manifest.permission.WRITE_SETTINGS;
import static android.net.TetheringManager.TETHERING_WIFI;
+import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION;
+import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.app.UiAutomation;
import android.content.Intent;
import android.net.IIntResultListener;
import android.net.ITetheringConnector;
import android.net.ITetheringEventCallback;
import android.net.TetheringRequestParcel;
+import android.os.Bundle;
+import android.os.Handler;
import android.os.ResultReceiver;
import androidx.test.InstrumentationRegistry;
@@ -51,13 +60,14 @@
@SmallTest
public final class TetheringServiceTest {
private static final String TEST_IFACE_NAME = "test_wlan0";
- private static final String TEST_CALLER_PKG = "test_pkg";
+ private static final String TEST_CALLER_PKG = "com.android.shell";
private static final String TEST_ATTRIBUTION_TAG = null;
@Mock private ITetheringEventCallback mITetheringEventCallback;
@Rule public ServiceTestRule mServiceTestRule;
private Tethering mTethering;
private Intent mMockServiceIntent;
private ITetheringConnector mTetheringConnector;
+ private UiAutomation mUiAutomation;
private class TestTetheringResult extends IIntResultListener.Stub {
private int mResult = -1; // Default value that does not match any result code.
@@ -71,9 +81,26 @@
}
}
+ private class MyResultReceiver extends ResultReceiver {
+ MyResultReceiver(Handler handler) {
+ super(handler);
+ }
+ private int mResult = -1; // Default value that does not match any result code.
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ mResult = resultCode;
+ }
+
+ public void assertResult(int expected) {
+ assertEquals(expected, mResult);
+ }
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ mUiAutomation =
+ InstrumentationRegistry.getInstrumentation().getUiAutomation();
mServiceTestRule = new ServiceTestRule();
mMockServiceIntent = new Intent(
InstrumentationRegistry.getTargetContext(),
@@ -83,115 +110,364 @@
mTetheringConnector = mockConnector.getTetheringConnector();
final MockTetheringService service = mockConnector.getService();
mTethering = service.getTethering();
- when(mTethering.isTetheringSupported()).thenReturn(true);
}
@After
public void tearDown() throws Exception {
mServiceTestRule.unbindService();
+ mUiAutomation.dropShellPermissionIdentity();
+ }
+
+ private interface TestTetheringCall {
+ void runTetheringCall(TestTetheringResult result) throws Exception;
+ }
+
+ private void runAsNoPermission(final TestTetheringCall test) throws Exception {
+ runTetheringCall(test, new String[0]);
+ }
+
+ private void runAsTetherPrivileged(final TestTetheringCall test) throws Exception {
+ runTetheringCall(test, TETHER_PRIVILEGED);
+ }
+
+ private void runAsAccessNetworkState(final TestTetheringCall test) throws Exception {
+ runTetheringCall(test, ACCESS_NETWORK_STATE);
+ }
+
+ private void runAsWriteSettings(final TestTetheringCall test) throws Exception {
+ runTetheringCall(test, WRITE_SETTINGS);
+ }
+
+ private void runTetheringCall(final TestTetheringCall test, String... permissions)
+ throws Exception {
+ if (permissions.length > 0) mUiAutomation.adoptShellPermissionIdentity(permissions);
+ try {
+ when(mTethering.isTetheringSupported()).thenReturn(true);
+ test.runTetheringCall(new TestTetheringResult());
+ } finally {
+ mUiAutomation.dropShellPermissionIdentity();
+ }
+ }
+
+ private void verifyNoMoreInteractionsForTethering() {
+ verifyNoMoreInteractions(mTethering);
+ verifyNoMoreInteractions(mITetheringEventCallback);
+ reset(mTethering, mITetheringEventCallback);
+ }
+
+ private void runTether(final TestTetheringResult result) throws Exception {
+ when(mTethering.tether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
+ mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
+ verify(mTethering).isTetheringSupported();
+ verify(mTethering).tether(TEST_IFACE_NAME);
+ result.assertResult(TETHER_ERROR_NO_ERROR);
}
@Test
public void testTether() throws Exception {
- when(mTethering.tether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
- final TestTetheringResult result = new TestTetheringResult();
- mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
+ runAsNoPermission((result) -> {
+ mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runTether(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runTether(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runUnTether(final TestTetheringResult result) throws Exception {
+ when(mTethering.untether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
+ mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
verify(mTethering).isTetheringSupported();
- verify(mTethering).tether(TEST_IFACE_NAME);
- verifyNoMoreInteractions(mTethering);
+ verify(mTethering).untether(TEST_IFACE_NAME);
result.assertResult(TETHER_ERROR_NO_ERROR);
}
@Test
public void testUntether() throws Exception {
- when(mTethering.untether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
- final TestTetheringResult result = new TestTetheringResult();
- mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
- result);
+ runAsNoPermission((result) -> {
+ mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runUnTether(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runUnTether(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runSetUsbTethering(final TestTetheringResult result) throws Exception {
+ when(mTethering.setUsbTethering(true /* enable */)).thenReturn(TETHER_ERROR_NO_ERROR);
+ mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
+ TEST_ATTRIBUTION_TAG, result);
verify(mTethering).isTetheringSupported();
- verify(mTethering).untether(TEST_IFACE_NAME);
- verifyNoMoreInteractions(mTethering);
+ verify(mTethering).setUsbTethering(true /* enable */);
result.assertResult(TETHER_ERROR_NO_ERROR);
}
@Test
public void testSetUsbTethering() throws Exception {
- when(mTethering.setUsbTethering(true /* enable */)).thenReturn(TETHER_ERROR_NO_ERROR);
- final TestTetheringResult result = new TestTetheringResult();
- mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
- TEST_ATTRIBUTION_TAG, result);
+ runAsNoPermission((result) -> {
+ mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
+ TEST_ATTRIBUTION_TAG, result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runSetUsbTethering(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runSetUsbTethering(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ }
+
+ private void runStartTethering(final TestTetheringResult result,
+ final TetheringRequestParcel request) throws Exception {
+ mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
verify(mTethering).isTetheringSupported();
- verify(mTethering).setUsbTethering(true /* enable */);
- verifyNoMoreInteractions(mTethering);
- result.assertResult(TETHER_ERROR_NO_ERROR);
+ verify(mTethering).startTethering(eq(request), eq(result));
}
@Test
public void testStartTethering() throws Exception {
- final TestTetheringResult result = new TestTetheringResult();
final TetheringRequestParcel request = new TetheringRequestParcel();
request.tetheringType = TETHERING_WIFI;
- mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
- verify(mTethering).isTetheringSupported();
- verify(mTethering).startTethering(eq(request), eq(result));
- verifyNoMoreInteractions(mTethering);
+
+ runAsNoPermission((result) -> {
+ mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runStartTethering(result, request);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runStartTethering(result, request);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
}
@Test
- public void testStopTethering() throws Exception {
- final TestTetheringResult result = new TestTetheringResult();
- mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
- result);
+ public void testStartTetheringWithExemptFromEntitlementCheck() throws Exception {
+ final TetheringRequestParcel request = new TetheringRequestParcel();
+ request.tetheringType = TETHERING_WIFI;
+ request.exemptFromEntitlementCheck = true;
+
+ runAsTetherPrivileged((result) -> {
+ runStartTethering(result, request);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runStopTethering(final TestTetheringResult result) throws Exception {
+ mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG,
+ TEST_ATTRIBUTION_TAG, result);
verify(mTethering).isTetheringSupported();
verify(mTethering).stopTethering(TETHERING_WIFI);
- verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR);
}
@Test
- public void testRequestLatestTetheringEntitlementResult() throws Exception {
- final ResultReceiver result = new ResultReceiver(null);
+ public void testStopTethering() throws Exception {
+ runAsNoPermission((result) -> {
+ mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG,
+ TEST_ATTRIBUTION_TAG, result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runStopTethering(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runStopTethering(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runRequestLatestTetheringEntitlementResult() throws Exception {
+ final MyResultReceiver result = new MyResultReceiver(null);
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
verify(mTethering).isTetheringSupported();
verify(mTethering).requestLatestTetheringEntitlementResult(eq(TETHERING_WIFI),
eq(result), eq(true) /* showEntitlementUi */);
+ }
+
+ @Test
+ public void testRequestLatestTetheringEntitlementResult() throws Exception {
+ // Run as no permission.
+ final MyResultReceiver result = new MyResultReceiver(null);
+ mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
+ true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
verifyNoMoreInteractions(mTethering);
+
+ runAsTetherPrivileged((none) -> {
+ runRequestLatestTetheringEntitlementResult();
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((none) -> {
+ runRequestLatestTetheringEntitlementResult();
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runRegisterTetheringEventCallback() throws Exception {
+ mTetheringConnector.registerTetheringEventCallback(mITetheringEventCallback,
+ TEST_CALLER_PKG);
+ verify(mTethering).registerTetheringEventCallback(eq(mITetheringEventCallback));
}
@Test
public void testRegisterTetheringEventCallback() throws Exception {
- mTetheringConnector.registerTetheringEventCallback(mITetheringEventCallback,
+ runAsNoPermission((result) -> {
+ mTetheringConnector.registerTetheringEventCallback(mITetheringEventCallback,
+ TEST_CALLER_PKG);
+ verify(mITetheringEventCallback).onCallbackStopped(
+ TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((none) -> {
+ runRegisterTetheringEventCallback();
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsAccessNetworkState((none) -> {
+ runRegisterTetheringEventCallback();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runUnregisterTetheringEventCallback() throws Exception {
+ mTetheringConnector.unregisterTetheringEventCallback(mITetheringEventCallback,
TEST_CALLER_PKG);
- verify(mTethering).registerTetheringEventCallback(eq(mITetheringEventCallback));
- verifyNoMoreInteractions(mTethering);
+ verify(mTethering).unregisterTetheringEventCallback(eq(mITetheringEventCallback));
}
@Test
public void testUnregisterTetheringEventCallback() throws Exception {
- mTetheringConnector.unregisterTetheringEventCallback(mITetheringEventCallback,
- TEST_CALLER_PKG);
- verify(mTethering).unregisterTetheringEventCallback(
- eq(mITetheringEventCallback));
- verifyNoMoreInteractions(mTethering);
+ runAsNoPermission((result) -> {
+ mTetheringConnector.unregisterTetheringEventCallback(mITetheringEventCallback,
+ TEST_CALLER_PKG);
+ verify(mITetheringEventCallback).onCallbackStopped(
+ TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((none) -> {
+ runUnregisterTetheringEventCallback();
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsAccessNetworkState((none) -> {
+ runUnregisterTetheringEventCallback();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runStopAllTethering(final TestTetheringResult result) throws Exception {
+ mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
+ verify(mTethering).isTetheringSupported();
+ verify(mTethering).untetherAll();
+ result.assertResult(TETHER_ERROR_NO_ERROR);
}
@Test
public void testStopAllTethering() throws Exception {
- final TestTetheringResult result = new TestTetheringResult();
- mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
+ runAsNoPermission((result) -> {
+ mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runStopAllTethering(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runStopAllTethering(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runIsTetheringSupported(final TestTetheringResult result) throws Exception {
+ mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
verify(mTethering).isTetheringSupported();
- verify(mTethering).untetherAll();
- verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR);
}
@Test
public void testIsTetheringSupported() throws Exception {
- final TestTetheringResult result = new TestTetheringResult();
- mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
- verify(mTethering).isTetheringSupported();
- verifyNoMoreInteractions(mTethering);
- result.assertResult(TETHER_ERROR_NO_ERROR);
+ runAsNoPermission((result) -> {
+ mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runIsTetheringSupported(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runIsTetheringSupported(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
}
}