diff --git a/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl b/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl index 8be79645bd..cf094aac2c 100644 --- a/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl +++ b/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl @@ -22,25 +22,31 @@ import android.os.ResultReceiver; /** @hide */ oneway interface ITetheringConnector { - void tether(String iface, String callerPkg, IIntResultListener receiver); - - void untether(String iface, String callerPkg, IIntResultListener receiver); - - void setUsbTethering(boolean enable, String callerPkg, IIntResultListener receiver); - - void startTethering(in TetheringRequestParcel request, String callerPkg, + void tether(String iface, String callerPkg, String callingAttributionTag, IIntResultListener receiver); - void stopTethering(int type, String callerPkg, IIntResultListener receiver); + void untether(String iface, String callerPkg, String callingAttributionTag, + IIntResultListener receiver); + + void setUsbTethering(boolean enable, String callerPkg, + String callingAttributionTag, IIntResultListener receiver); + + void startTethering(in TetheringRequestParcel request, String callerPkg, + String callingAttributionTag, IIntResultListener receiver); + + void stopTethering(int type, String callerPkg, String callingAttributionTag, + IIntResultListener receiver); void requestLatestTetheringEntitlementResult(int type, in ResultReceiver receiver, - boolean showEntitlementUi, String callerPkg); + boolean showEntitlementUi, String callerPkg, String callingAttributionTag); void registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg); void unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg); - void isTetheringSupported(String callerPkg, IIntResultListener receiver); + void isTetheringSupported(String callerPkg, String callingAttributionTag, + IIntResultListener receiver); - void stopAllTethering(String callerPkg, IIntResultListener receiver); + void stopAllTethering(String callerPkg, String callingAttributionTag, + IIntResultListener receiver); } diff --git a/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/Tethering/common/TetheringLib/src/android/net/TetheringManager.java index cc095a0bb4..4a8ccea5f2 100644 --- a/Tethering/common/TetheringLib/src/android/net/TetheringManager.java +++ b/Tethering/common/TetheringLib/src/android/net/TetheringManager.java @@ -484,13 +484,20 @@ public class TetheringManager { return dispatcher.waitForResult((connector, listener) -> { try { - connector.tether(iface, callerPkg, listener); + connector.tether(iface, callerPkg, getAttributionTag(), listener); } catch (RemoteException e) { throw new IllegalStateException(e); } }); } + /** + * @return the context's attribution tag + */ + private @Nullable String getAttributionTag() { + return mContext.getAttributionTag(); + } + /** * Stop tethering the named interface. * @@ -509,7 +516,7 @@ public class TetheringManager { return dispatcher.waitForResult((connector, listener) -> { try { - connector.untether(iface, callerPkg, listener); + connector.untether(iface, callerPkg, getAttributionTag(), listener); } catch (RemoteException e) { throw new IllegalStateException(e); } @@ -536,7 +543,8 @@ public class TetheringManager { return dispatcher.waitForResult((connector, listener) -> { try { - connector.setUsbTethering(enable, callerPkg, listener); + connector.setUsbTethering(enable, callerPkg, getAttributionTag(), + listener); } catch (RemoteException e) { throw new IllegalStateException(e); } @@ -735,7 +743,8 @@ public class TetheringManager { }); } }; - getConnector(c -> c.startTethering(request.getParcel(), callerPkg, listener)); + getConnector(c -> c.startTethering(request.getParcel(), callerPkg, + getAttributionTag(), listener)); } /** @@ -775,7 +784,8 @@ public class TetheringManager { final String callerPkg = mContext.getOpPackageName(); Log.i(TAG, "stopTethering caller:" + callerPkg); - getConnector(c -> c.stopTethering(type, callerPkg, new IIntResultListener.Stub() { + getConnector(c -> c.stopTethering(type, callerPkg, getAttributionTag(), + new IIntResultListener.Stub() { @Override public void onResult(int resultCode) { // TODO: provide an API to obtain result @@ -861,7 +871,7 @@ public class TetheringManager { Log.i(TAG, "getLatestTetheringEntitlementResult caller:" + callerPkg); getConnector(c -> c.requestLatestTetheringEntitlementResult( - type, receiver, showEntitlementUi, callerPkg)); + type, receiver, showEntitlementUi, callerPkg, getAttributionTag())); } /** @@ -1312,7 +1322,7 @@ public class TetheringManager { final RequestDispatcher dispatcher = new RequestDispatcher(); final int ret = dispatcher.waitForResult((connector, listener) -> { try { - connector.isTetheringSupported(callerPkg, listener); + connector.isTetheringSupported(callerPkg, getAttributionTag(), listener); } catch (RemoteException e) { throw new IllegalStateException(e); } @@ -1335,14 +1345,15 @@ public class TetheringManager { final String callerPkg = mContext.getOpPackageName(); Log.i(TAG, "stopAllTethering caller:" + callerPkg); - getConnector(c -> c.stopAllTethering(callerPkg, new IIntResultListener.Stub() { - @Override - public void onResult(int resultCode) { - // TODO: add an API parameter to send result to caller. - // This has never been possible as stopAllTethering has always been void and never - // taken a callback object. The only indication that callers have is if the call - // results in a TETHER_STATE_CHANGE broadcast. - } - })); + getConnector(c -> c.stopAllTethering(callerPkg, getAttributionTag(), + new IIntResultListener.Stub() { + @Override + public void onResult(int resultCode) { + // TODO: add an API parameter to send result to caller. + // This has never been possible as stopAllTethering has always been void + // and never taken a callback object. The only indication that callers have + // is if the call results in a TETHER_STATE_CHANGE broadcast. + } + })); } } diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringService.java b/Tethering/src/com/android/networkstack/tethering/TetheringService.java index 3ed211520d..08011f0497 100644 --- a/Tethering/src/com/android/networkstack/tethering/TetheringService.java +++ b/Tethering/src/com/android/networkstack/tethering/TetheringService.java @@ -119,8 +119,9 @@ public class TetheringService extends Service { } @Override - public void tether(String iface, String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void tether(String iface, String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { listener.onResult(mTethering.tether(iface)); @@ -128,8 +129,9 @@ public class TetheringService extends Service { } @Override - public void untether(String iface, String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void untether(String iface, String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { listener.onResult(mTethering.untether(iface)); @@ -137,8 +139,9 @@ public class TetheringService extends Service { } @Override - public void setUsbTethering(boolean enable, String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void setUsbTethering(boolean enable, String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { listener.onResult(mTethering.setUsbTethering(enable)); @@ -147,15 +150,16 @@ public class TetheringService extends Service { @Override public void startTethering(TetheringRequestParcel request, String callerPkg, - IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + String callingAttributionTag, IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; mTethering.startTethering(request, listener); } @Override - public void stopTethering(int type, String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void stopTethering(int type, String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { mTethering.stopTethering(type); @@ -165,8 +169,8 @@ public class TetheringService extends Service { @Override public void requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver, - boolean showEntitlementUi, String callerPkg) { - if (checkAndNotifyCommonError(callerPkg, receiver)) return; + boolean showEntitlementUi, String callerPkg, String callingAttributionTag) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, receiver)) return; mTethering.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi); } @@ -196,8 +200,9 @@ public class TetheringService extends Service { } @Override - public void stopAllTethering(String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void stopAllTethering(String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { mTethering.untetherAll(); @@ -206,8 +211,9 @@ public class TetheringService extends Service { } @Override - public void isTetheringSupported(String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void isTetheringSupported(String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { listener.onResult(TETHER_ERROR_NO_ERROR); @@ -220,9 +226,10 @@ public class TetheringService extends Service { mTethering.dump(fd, writer, args); } - private boolean checkAndNotifyCommonError(String callerPkg, IIntResultListener listener) { + private boolean checkAndNotifyCommonError(String callerPkg, String callingAttributionTag, + IIntResultListener listener) { try { - if (!mService.hasTetherChangePermission(callerPkg)) { + if (!mService.hasTetherChangePermission(callerPkg, callingAttributionTag)) { listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); return true; } @@ -237,8 +244,9 @@ public class TetheringService extends Service { return false; } - private boolean checkAndNotifyCommonError(String callerPkg, ResultReceiver receiver) { - if (!mService.hasTetherChangePermission(callerPkg)) { + private boolean checkAndNotifyCommonError(String callerPkg, String callingAttributionTag, + ResultReceiver receiver) { + if (!mService.hasTetherChangePermission(callerPkg, callingAttributionTag)) { receiver.send(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, null); return true; } @@ -266,7 +274,7 @@ public class TetheringService extends Service { return tetherEnabledInSettings && mTethering.hasTetherableConfiguration(); } - private boolean hasTetherChangePermission(String callerPkg) { + private boolean hasTetherChangePermission(String callerPkg, String callingAttributionTag) { if (checkCallingOrSelfPermission( android.Manifest.permission.TETHER_PRIVILEGED) == PERMISSION_GRANTED) { return true; @@ -278,14 +286,28 @@ public class TetheringService extends Service { int uid = Binder.getCallingUid(); // If callerPkg's uid is not same as Binder.getCallingUid(), // checkAndNoteWriteSettingsOperation will return false and the operation will be denied. - if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid, callerPkg, - false /* throwException */)) { + if (checkAndNoteWriteSettingsOperation(mContext, uid, callerPkg, + callingAttributionTag, false /* throwException */)) { return true; } return false; } + /** + * Check if the package is a allowed to write settings. This also accounts that such an access + * happened. + * + * @return {@code true} iff the package is allowed to write settings. + */ + // TODO: Remove method and replace with direct call once R code is pushed to AOSP + private static boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid, + @NonNull String callingPackage, @Nullable String callingAttributionTag, + boolean throwException) { + return Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPackage, + callingAttributionTag, throwException); + } + private boolean hasTetherAccessPermission() { if (checkCallingOrSelfPermission( android.Manifest.permission.TETHER_PRIVILEGED) == PERMISSION_GRANTED) { 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 51bad9af23..7df9fc6850 100644 --- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java +++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java @@ -52,6 +52,7 @@ import org.mockito.MockitoAnnotations; 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_ATTRIBUTION_TAG = null; @Mock private ITetheringEventCallback mITetheringEventCallback; @Rule public ServiceTestRule mServiceTestRule; private Tethering mTethering; @@ -95,7 +96,7 @@ public final class TetheringServiceTest { 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, result); + mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); verify(mTethering).hasTetherableConfiguration(); verify(mTethering).tether(TEST_IFACE_NAME); verifyNoMoreInteractions(mTethering); @@ -106,7 +107,8 @@ public final class TetheringServiceTest { 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, result); + mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, + result); verify(mTethering).hasTetherableConfiguration(); verify(mTethering).untether(TEST_IFACE_NAME); verifyNoMoreInteractions(mTethering); @@ -117,7 +119,8 @@ public final class TetheringServiceTest { 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, result); + mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG, + TEST_ATTRIBUTION_TAG, result); verify(mTethering).hasTetherableConfiguration(); verify(mTethering).setUsbTethering(true /* enable */); verifyNoMoreInteractions(mTethering); @@ -129,7 +132,7 @@ public final class TetheringServiceTest { final TestTetheringResult result = new TestTetheringResult(); final TetheringRequestParcel request = new TetheringRequestParcel(); request.tetheringType = TETHERING_WIFI; - mTetheringConnector.startTethering(request, TEST_CALLER_PKG, result); + mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); verify(mTethering).hasTetherableConfiguration(); verify(mTethering).startTethering(eq(request), eq(result)); verifyNoMoreInteractions(mTethering); @@ -138,7 +141,8 @@ public final class TetheringServiceTest { @Test public void testStopTethering() throws Exception { final TestTetheringResult result = new TestTetheringResult(); - mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, result); + mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, + result); verify(mTethering).hasTetherableConfiguration(); verify(mTethering).stopTethering(TETHERING_WIFI); verifyNoMoreInteractions(mTethering); @@ -149,7 +153,7 @@ public final class TetheringServiceTest { public void testRequestLatestTetheringEntitlementResult() throws Exception { final ResultReceiver result = new ResultReceiver(null); mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result, - true /* showEntitlementUi */, TEST_CALLER_PKG); + true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG); verify(mTethering).hasTetherableConfiguration(); verify(mTethering).requestLatestTetheringEntitlementResult(eq(TETHERING_WIFI), eq(result), eq(true) /* showEntitlementUi */); @@ -176,7 +180,7 @@ public final class TetheringServiceTest { @Test public void testStopAllTethering() throws Exception { final TestTetheringResult result = new TestTetheringResult(); - mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, result); + mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); verify(mTethering).hasTetherableConfiguration(); verify(mTethering).untetherAll(); verifyNoMoreInteractions(mTethering); @@ -186,7 +190,7 @@ public final class TetheringServiceTest { @Test public void testIsTetheringSupported() throws Exception { final TestTetheringResult result = new TestTetheringResult(); - mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, result); + mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); verify(mTethering).hasTetherableConfiguration(); verifyNoMoreInteractions(mTethering); result.assertResult(TETHER_ERROR_NO_ERROR);