diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java index a80f5b7f36d4e..bfc28fae6e658 100644 --- a/core/java/android/bluetooth/BluetoothPan.java +++ b/core/java/android/bluetooth/BluetoothPan.java @@ -367,7 +367,7 @@ public final class BluetoothPan implements BluetoothProfile { final IBluetoothPan service = getService(); if (service != null && isEnabled()) { try { - service.setBluetoothTethering(value, pkgName); + service.setBluetoothTethering(value, pkgName, null); } catch (RemoteException e) { Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); } diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 7332ede0b997a..e860411520f55 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -2043,12 +2043,21 @@ public class ConnectivityManager { public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) { checkLegacyRoutingApiAccess(); try { - return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress()); + return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress(), + mContext.getOpPackageName(), getAttributionTag()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } + /** + * @return the context's attribution tag + */ + // TODO: Remove method and replace with direct call once R code is pushed to AOSP + private @Nullable String getAttributionTag() { + return null; + } + /** * Returns the value of the setting for background data usage. If false, * applications should not use the network if the application is not in the @@ -2239,14 +2248,30 @@ public class ConnectivityManager { * services.jar, possibly in com.android.server.net. */ /** {@hide} */ - public static final void enforceChangePermission(Context context) { + public static final void enforceChangePermission(Context context, + String callingPkg, String callingAttributionTag) { int uid = Binder.getCallingUid(); - Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings - .getPackageNameForUid(context, uid), true /* throwException */); + checkAndNoteChangeNetworkStateOperation(context, uid, callingPkg, + callingAttributionTag, true /* throwException */); + } + + /** + * Check if the package is a allowed to change the network state. This also accounts that such + * an access happened. + * + * @return {@code true} iff the package is allowed to change the network state. + */ + // TODO: Remove method and replace with direct call once R code is pushed to AOSP + private static boolean checkAndNoteChangeNetworkStateOperation(@NonNull Context context, + int uid, @NonNull String callingPackage, @Nullable String callingAttributionTag, + boolean throwException) { + return Settings.checkAndNoteChangeNetworkStateOperation(context, uid, callingPackage, + throwException); } /** {@hide} */ - public static final void enforceTetherChangePermission(Context context, String callingPkg) { + public static final void enforceTetherChangePermission(Context context, String callingPkg, + String callingAttributionTag) { Preconditions.checkNotNull(context, "Context cannot be null"); Preconditions.checkNotNull(callingPkg, "callingPkg cannot be null"); @@ -2260,11 +2285,25 @@ public class ConnectivityManager { int uid = Binder.getCallingUid(); // If callingPkg's uid is not same as Binder.getCallingUid(), // AppOpsService throws SecurityException. - Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPkg, - true /* throwException */); + checkAndNoteWriteSettingsOperation(context, uid, callingPkg, + callingAttributionTag, true /* throwException */); } } + /** + * 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, + throwException); + } + /** * @deprecated - use getSystemService. This is a kludge to support static access in certain * situations where a Context pointer is unavailable. @@ -3705,7 +3744,8 @@ public class ConnectivityManager { need, messenger, binder, callingPackageName); } else { request = mService.requestNetwork( - need, messenger, timeoutMs, binder, legacyType, callingPackageName); + need, messenger, timeoutMs, binder, legacyType, callingPackageName, + getAttributionTag()); } if (request != null) { sCallbacks.put(request, callback); @@ -3981,7 +4021,8 @@ public class ConnectivityManager { checkPendingIntentNotNull(operation); try { mService.pendingRequestForNetwork( - request.networkCapabilities, operation, mContext.getOpPackageName()); + request.networkCapabilities, operation, mContext.getOpPackageName(), + getAttributionTag()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } catch (ServiceSpecificException e) { diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 14345608e94f2..b0f79bcc0b233 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -77,7 +77,8 @@ interface IConnectivityManager NetworkQuotaInfo getActiveNetworkQuotaInfo(); boolean isActiveNetworkMetered(); - boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress); + boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, + String callingPackageName, String callingAttributionTag); @UnsupportedAppUsage(maxTargetSdk = 29, publicAlternatives = "Use {@code TetheringManager#getLastTetherError} as alternative") @@ -168,10 +169,10 @@ interface IConnectivityManager NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, in Messenger messenger, int timeoutSec, in IBinder binder, int legacy, - String callingPackageName); + String callingPackageName, String callingAttributionTag); NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities, - in PendingIntent operation, String callingPackageName); + in PendingIntent operation, String callingPackageName, String callingAttributionTag); void releasePendingNetworkRequest(in PendingIntent operation); diff --git a/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl b/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl index 8be79645bde32..cf094aac2cbe9 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl +++ b/packages/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/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java index cc095a0bb4a78..05af5c9d0ef10 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java +++ b/packages/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 null; + } + /** * 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/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java index 3ed211520db69..c82e2be72ad2a 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java +++ b/packages/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, + throwException); + } + private boolean hasTetherAccessPermission() { if (checkCallingOrSelfPermission( android.Manifest.permission.TETHER_PRIVILEGED) == PERMISSION_GRANTED) { diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java index 51bad9af23efb..7df9fc6850534 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java +++ b/packages/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); diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 552331ede99b4..857d22609416f 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1819,11 +1819,12 @@ public class ConnectivityService extends IConnectivityManager.Stub * @return {@code true} on success, {@code false} on failure */ @Override - public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) { + public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress, + String callingPackageName, String callingAttributionTag) { if (disallowedBecauseSystemCaller()) { return false; } - enforceChangePermission(); + enforceChangePermission(callingPackageName, callingAttributionTag); if (mProtectedNetworks.contains(networkType)) { enforceConnectivityRestrictedNetworksPermission(); } @@ -2077,8 +2078,8 @@ public class ConnectivityService extends IConnectivityManager.Stub "ConnectivityService"); } - private void enforceChangePermission() { - ConnectivityManager.enforceChangePermission(mContext); + private void enforceChangePermission(String callingPkg, String callingAttributionTag) { + ConnectivityManager.enforceChangePermission(mContext, callingPkg, callingAttributionTag); } private void enforceSettingsPermission() { @@ -5439,7 +5440,7 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, int timeoutMs, IBinder binder, int legacyType, - @NonNull String callingPackageName) { + @NonNull String callingPackageName, @Nullable String callingAttributionTag) { if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) { if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) { throw new SecurityException("Insufficient permissions to specify legacy type"); @@ -5457,7 +5458,8 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceAccessPermission(); } else { networkCapabilities = new NetworkCapabilities(networkCapabilities); - enforceNetworkRequestPermissions(networkCapabilities); + enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, + callingAttributionTag); // TODO: this is incorrect. We mark the request as metered or not depending on the state // of the app when the request is filed, but we never change the request if the app // changes network state. http://b/29964605 @@ -5492,11 +5494,12 @@ public class ConnectivityService extends IConnectivityManager.Stub return networkRequest; } - private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) { + private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities, + String callingPackageName, String callingAttributionTag) { if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) { enforceConnectivityRestrictedNetworksPermission(); } else { - enforceChangePermission(); + enforceChangePermission(callingPackageName, callingAttributionTag); } } @@ -5547,11 +5550,13 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, - PendingIntent operation, @NonNull String callingPackageName) { + PendingIntent operation, @NonNull String callingPackageName, + @Nullable String callingAttributionTag) { Objects.requireNonNull(operation, "PendingIntent cannot be null."); final int callingUid = Binder.getCallingUid(); networkCapabilities = new NetworkCapabilities(networkCapabilities); - enforceNetworkRequestPermissions(networkCapabilities); + enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, + callingAttributionTag); enforceMeteredApnPolicy(networkCapabilities); ensureRequestableCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java index d6bf334ee56a8..d74a621842f91 100644 --- a/tests/net/java/android/net/ConnectivityManagerTest.java +++ b/tests/net/java/android/net/ConnectivityManagerTest.java @@ -36,6 +36,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; @@ -213,7 +214,7 @@ public class ConnectivityManagerTest { // register callback when(mService.requestNetwork( - any(), captor.capture(), anyInt(), any(), anyInt(), any())) + any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class))) .thenReturn(request); manager.requestNetwork(request, callback, handler); @@ -242,7 +243,7 @@ public class ConnectivityManagerTest { // register callback when(mService.requestNetwork( - any(), captor.capture(), anyInt(), any(), anyInt(), any())) + any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class))) .thenReturn(req1); manager.requestNetwork(req1, callback, handler); @@ -261,7 +262,7 @@ public class ConnectivityManagerTest { // callback can be registered again when(mService.requestNetwork( - any(), captor.capture(), anyInt(), any(), anyInt(), any())) + any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class))) .thenReturn(req2); manager.requestNetwork(req2, callback, handler); @@ -285,8 +286,8 @@ public class ConnectivityManagerTest { info.targetSdkVersion = VERSION_CODES.N_MR1 + 1; when(mCtx.getApplicationInfo()).thenReturn(info); - when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any())) - .thenReturn(request); + when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any(), + nullable(String.class))).thenReturn(request); Handler handler = new Handler(Looper.getMainLooper()); manager.requestNetwork(request, callback, handler); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index a478e68c7dba6..aa5c9415673c1 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -3049,6 +3049,13 @@ public class ConnectivityServiceTest { assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); } + /** + * @return the context's attribution tag + */ + private String getAttributionTag() { + return null; + } + @Test public void testInvalidNetworkSpecifier() { assertThrows(IllegalArgumentException.class, () -> { @@ -3061,7 +3068,8 @@ public class ConnectivityServiceTest { networkCapabilities.addTransportType(TRANSPORT_WIFI) .setNetworkSpecifier(new MatchAllNetworkSpecifier()); mService.requestNetwork(networkCapabilities, null, 0, null, - ConnectivityManager.TYPE_WIFI, mContext.getPackageName()); + ConnectivityManager.TYPE_WIFI, mContext.getPackageName(), + getAttributionTag()); }); class NonParcelableSpecifier extends NetworkSpecifier {