Loading android/app/aidl/android/bluetooth/IBluetoothGatt.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -179,8 +179,8 @@ interface IBluetoothGatt { @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void leSubrateRequest(in int clientIf, in String address, in int subrateMin, in int subrateMax, in int maxLatency, in int contNumber, in int supervisionTimeout, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void subrateModeRequest(in int clientIf, in String address, in int subrateMode, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED}, conditional=true)") int subrateModeRequest(in int clientIf, in BluetoothDevice device, in int subrateMode, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") List<DistanceMeasurementMethod> getSupportedDistanceMeasurementMethods(in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") Loading android/app/jni/com_android_bluetooth_gatt.cpp +7 −5 Original line number Diff line number Diff line Loading @@ -2046,14 +2046,16 @@ static void gattConnectionParameterUpdateNative(JNIEnv* env, jobject /* object * (uint16_t)max_ce_len); } static void gattSubrateRequestNative(JNIEnv* env, jobject /* object */, jint /* client_if */, static int gattSubrateRequestNative(JNIEnv* env, jobject /* object */, jint /* client_if */, jstring address, jint subrate_min, jint subrate_max, jint max_latency, jint cont_num, jint sup_timeout) { if (!sGattIf) { return; return 1; // BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED } // TODO does bt_status_t align with BluetoothStatusCodes ? sGattIf->client->subrate_request(str2addr(env, address), subrate_min, subrate_max, max_latency, cont_num, sup_timeout); return 0; // BluetoothStatusCodes.SUCCESS } void batchscan_cfg_storage_cb(uint8_t client_if, uint8_t status) { Loading Loading @@ -3060,7 +3062,7 @@ static int register_com_android_bluetooth_gatt_(JNIEnv* env) { {"gattServerSendIndicationNative", "(III[B)V", (void*)gattServerSendIndicationNative}, {"gattServerSendNotificationNative", "(III[B)V", (void*)gattServerSendNotificationNative}, {"gattServerSendResponseNative", "(IIIIII[BI)V", (void*)gattServerSendResponseNative}, {"gattSubrateRequestNative", "(ILjava/lang/String;IIIII)V", {"gattSubrateRequestNative", "(ILjava/lang/String;IIIII)I", (void*)gattSubrateRequestNative}, {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void*)gattTestNative}, Loading android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java +3 −3 Original line number Diff line number Diff line Loading @@ -382,7 +382,7 @@ public class GattNativeInterface { byte[] val, int authReq); private native void gattSubrateRequestNative( private native int gattSubrateRequestNative( int clientIf, String address, int subrateMin, Loading Loading @@ -570,7 +570,7 @@ public class GattNativeInterface { } /** Update connection parameter. */ public void gattSubrateRequest( public int gattSubrateRequest( int clientIf, String address, int subrateMin, Loading @@ -578,7 +578,7 @@ public class GattNativeInterface { int maxLatency, int contNumber, int supervisionTimeout) { gattSubrateRequestNative( return gattSubrateRequestNative( clientIf, address, subrateMin, Loading android/app/src/com/android/bluetooth/gatt/GattService.java +38 −27 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import android.bluetooth.le.PeriodicAdvertisingParameters; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanSettings; import android.companion.CompanionDeviceManager; import android.content.AttributionSource; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; Loading Loading @@ -180,6 +181,7 @@ public class GattService extends ProfileService { private final AdapterService mAdapterService; private final AdvertiseManager mAdvertiseManager; private final GattNativeInterface mNativeInterface; private final CompanionDeviceManager mCompanionDeviceManager; private final DistanceMeasurementManager mDistanceMeasurementManager; private final ActivityManager mActivityManager; private final PackageManager mPackageManager; Loading @@ -192,6 +194,7 @@ public class GattService extends ProfileService { mAdapterService = adapterService; mActivityManager = requireNonNull(getSystemService(ActivityManager.class)); mPackageManager = requireNonNull(mAdapterService.getPackageManager()); mCompanionDeviceManager = requireNonNull(getSystemService(CompanionDeviceManager.class)); mTransitionalScanHelper = new TransitionalScanHelper(adapterService, this::isTestModeEnabled); Loading Loading @@ -808,16 +811,39 @@ public class GattService extends ProfileService { } @Override public void subrateModeRequest( public int subrateModeRequest( int clientIf, String address, BluetoothDevice device, int subrateMode, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; } if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "subrateModeRequest")) { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; } if (!Utils.checkConnectPermissionForDataDelivery( service, attributionSource, "GattService subrateModeRequest")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } service.subrateModeRequest(clientIf, address, subrateMode, attributionSource); Utils.enforceCdmAssociationIfNotBluetoothPrivileged( service, service.mCompanionDeviceManager, attributionSource, device); if (subrateMode < BluetoothGatt.SUBRATE_REQUEST_MODE_BALANCED || subrateMode > BluetoothGatt.SUBRATE_REQUEST_MODE_LOW_POWER) { throw new IllegalArgumentException("Subrate Mode not within valid range"); } requireNonNull(device); String address = device.getAddress(); if (!BluetoothAdapter.checkBluetoothAddress(address)) { throw new IllegalArgumentException("Invalid device address: " + address); } return service.subrateModeRequest(clientIf, device, subrateMode); } @Override Loading Loading @@ -2855,14 +2881,7 @@ public class GattService extends ProfileService { maxConnectionEventLen); } @RequiresPermission(BLUETOOTH_CONNECT) void subrateModeRequest( int clientIf, String address, int subrateMode, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService subrateModeRequest")) { return; } private int subrateModeRequest(int clientIf, BluetoothDevice device, int subrateMode) { int subrateMin; int subrateMax; int maxLatency; Loading Loading @@ -2898,23 +2917,15 @@ public class GattService extends ProfileService { Log.d( TAG, "subrateModeRequest() - " + "address=" + BluetoothUtils.toAnonymizedAddress(address) + ", subrate min/max=" + subrateMin + "/" + subrateMax + ", maxLatency=" + maxLatency + ", continuation Number=" + contNumber + ", timeout=" + supervisionTimeout); ("subrateModeRequest(" + device + ", " + subrateMode + "): ") + (", subrate min/max=" + subrateMin + "/" + subrateMax) + (", maxLatency=" + maxLatency) + (", continuationNumber=" + contNumber) + (", timeout=" + supervisionTimeout)); mNativeInterface.gattSubrateRequest( return mNativeInterface.gattSubrateRequest( clientIf, address, device.getAddress(), subrateMin, subrateMax, maxLatency, Loading android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java +8 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.bluetooth.le.DistanceMeasurementMethod; import android.bluetooth.le.DistanceMeasurementParams; import android.bluetooth.le.IDistanceMeasurementCallback; import android.bluetooth.le.PeriodicAdvertisingParameters; import android.companion.CompanionDeviceManager; import android.content.AttributionSource; import android.content.Context; import android.content.res.Resources; Loading Loading @@ -102,6 +103,8 @@ public class GattServiceTest { private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter(); private final AttributionSource mAttributionSource = mAdapter.getAttributionSource(); private final Context mContext = InstrumentationRegistry.getTargetContext(); private final CompanionDeviceManager mCompanionDeviceManager = mContext.getSystemService(CompanionDeviceManager.class); private MockContentResolver mMockContentResolver; Loading Loading @@ -141,6 +144,11 @@ public class GattServiceTest { mAdapterService, Context.LOCATION_SERVICE, LocationManager.class); TestUtils.mockGetSystemService( mAdapterService, Context.ACTIVITY_SERVICE, ActivityManager.class); TestUtils.mockGetSystemService( mAdapterService, Context.COMPANION_DEVICE_SERVICE, CompanionDeviceManager.class, mCompanionDeviceManager); mBtCompanionManager = new CompanionManager(mAdapterService, null); doReturn(mBtCompanionManager).when(mAdapterService).getCompanionManager(); Loading Loading
android/app/aidl/android/bluetooth/IBluetoothGatt.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -179,8 +179,8 @@ interface IBluetoothGatt { @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void leSubrateRequest(in int clientIf, in String address, in int subrateMin, in int subrateMax, in int maxLatency, in int contNumber, in int supervisionTimeout, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void subrateModeRequest(in int clientIf, in String address, in int subrateMode, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED}, conditional=true)") int subrateModeRequest(in int clientIf, in BluetoothDevice device, in int subrateMode, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") List<DistanceMeasurementMethod> getSupportedDistanceMeasurementMethods(in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") Loading
android/app/jni/com_android_bluetooth_gatt.cpp +7 −5 Original line number Diff line number Diff line Loading @@ -2046,14 +2046,16 @@ static void gattConnectionParameterUpdateNative(JNIEnv* env, jobject /* object * (uint16_t)max_ce_len); } static void gattSubrateRequestNative(JNIEnv* env, jobject /* object */, jint /* client_if */, static int gattSubrateRequestNative(JNIEnv* env, jobject /* object */, jint /* client_if */, jstring address, jint subrate_min, jint subrate_max, jint max_latency, jint cont_num, jint sup_timeout) { if (!sGattIf) { return; return 1; // BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED } // TODO does bt_status_t align with BluetoothStatusCodes ? sGattIf->client->subrate_request(str2addr(env, address), subrate_min, subrate_max, max_latency, cont_num, sup_timeout); return 0; // BluetoothStatusCodes.SUCCESS } void batchscan_cfg_storage_cb(uint8_t client_if, uint8_t status) { Loading Loading @@ -3060,7 +3062,7 @@ static int register_com_android_bluetooth_gatt_(JNIEnv* env) { {"gattServerSendIndicationNative", "(III[B)V", (void*)gattServerSendIndicationNative}, {"gattServerSendNotificationNative", "(III[B)V", (void*)gattServerSendNotificationNative}, {"gattServerSendResponseNative", "(IIIIII[BI)V", (void*)gattServerSendResponseNative}, {"gattSubrateRequestNative", "(ILjava/lang/String;IIIII)V", {"gattSubrateRequestNative", "(ILjava/lang/String;IIIII)I", (void*)gattSubrateRequestNative}, {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void*)gattTestNative}, Loading
android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java +3 −3 Original line number Diff line number Diff line Loading @@ -382,7 +382,7 @@ public class GattNativeInterface { byte[] val, int authReq); private native void gattSubrateRequestNative( private native int gattSubrateRequestNative( int clientIf, String address, int subrateMin, Loading Loading @@ -570,7 +570,7 @@ public class GattNativeInterface { } /** Update connection parameter. */ public void gattSubrateRequest( public int gattSubrateRequest( int clientIf, String address, int subrateMin, Loading @@ -578,7 +578,7 @@ public class GattNativeInterface { int maxLatency, int contNumber, int supervisionTimeout) { gattSubrateRequestNative( return gattSubrateRequestNative( clientIf, address, subrateMin, Loading
android/app/src/com/android/bluetooth/gatt/GattService.java +38 −27 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import android.bluetooth.le.PeriodicAdvertisingParameters; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanSettings; import android.companion.CompanionDeviceManager; import android.content.AttributionSource; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; Loading Loading @@ -180,6 +181,7 @@ public class GattService extends ProfileService { private final AdapterService mAdapterService; private final AdvertiseManager mAdvertiseManager; private final GattNativeInterface mNativeInterface; private final CompanionDeviceManager mCompanionDeviceManager; private final DistanceMeasurementManager mDistanceMeasurementManager; private final ActivityManager mActivityManager; private final PackageManager mPackageManager; Loading @@ -192,6 +194,7 @@ public class GattService extends ProfileService { mAdapterService = adapterService; mActivityManager = requireNonNull(getSystemService(ActivityManager.class)); mPackageManager = requireNonNull(mAdapterService.getPackageManager()); mCompanionDeviceManager = requireNonNull(getSystemService(CompanionDeviceManager.class)); mTransitionalScanHelper = new TransitionalScanHelper(adapterService, this::isTestModeEnabled); Loading Loading @@ -808,16 +811,39 @@ public class GattService extends ProfileService { } @Override public void subrateModeRequest( public int subrateModeRequest( int clientIf, String address, BluetoothDevice device, int subrateMode, AttributionSource attributionSource) { GattService service = getService(); if (service == null) { return; return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; } if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "subrateModeRequest")) { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; } if (!Utils.checkConnectPermissionForDataDelivery( service, attributionSource, "GattService subrateModeRequest")) { return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; } service.subrateModeRequest(clientIf, address, subrateMode, attributionSource); Utils.enforceCdmAssociationIfNotBluetoothPrivileged( service, service.mCompanionDeviceManager, attributionSource, device); if (subrateMode < BluetoothGatt.SUBRATE_REQUEST_MODE_BALANCED || subrateMode > BluetoothGatt.SUBRATE_REQUEST_MODE_LOW_POWER) { throw new IllegalArgumentException("Subrate Mode not within valid range"); } requireNonNull(device); String address = device.getAddress(); if (!BluetoothAdapter.checkBluetoothAddress(address)) { throw new IllegalArgumentException("Invalid device address: " + address); } return service.subrateModeRequest(clientIf, device, subrateMode); } @Override Loading Loading @@ -2855,14 +2881,7 @@ public class GattService extends ProfileService { maxConnectionEventLen); } @RequiresPermission(BLUETOOTH_CONNECT) void subrateModeRequest( int clientIf, String address, int subrateMode, AttributionSource attributionSource) { if (!Utils.checkConnectPermissionForDataDelivery( this, attributionSource, "GattService subrateModeRequest")) { return; } private int subrateModeRequest(int clientIf, BluetoothDevice device, int subrateMode) { int subrateMin; int subrateMax; int maxLatency; Loading Loading @@ -2898,23 +2917,15 @@ public class GattService extends ProfileService { Log.d( TAG, "subrateModeRequest() - " + "address=" + BluetoothUtils.toAnonymizedAddress(address) + ", subrate min/max=" + subrateMin + "/" + subrateMax + ", maxLatency=" + maxLatency + ", continuation Number=" + contNumber + ", timeout=" + supervisionTimeout); ("subrateModeRequest(" + device + ", " + subrateMode + "): ") + (", subrate min/max=" + subrateMin + "/" + subrateMax) + (", maxLatency=" + maxLatency) + (", continuationNumber=" + contNumber) + (", timeout=" + supervisionTimeout)); mNativeInterface.gattSubrateRequest( return mNativeInterface.gattSubrateRequest( clientIf, address, device.getAddress(), subrateMin, subrateMax, maxLatency, Loading
android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java +8 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.bluetooth.le.DistanceMeasurementMethod; import android.bluetooth.le.DistanceMeasurementParams; import android.bluetooth.le.IDistanceMeasurementCallback; import android.bluetooth.le.PeriodicAdvertisingParameters; import android.companion.CompanionDeviceManager; import android.content.AttributionSource; import android.content.Context; import android.content.res.Resources; Loading Loading @@ -102,6 +103,8 @@ public class GattServiceTest { private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter(); private final AttributionSource mAttributionSource = mAdapter.getAttributionSource(); private final Context mContext = InstrumentationRegistry.getTargetContext(); private final CompanionDeviceManager mCompanionDeviceManager = mContext.getSystemService(CompanionDeviceManager.class); private MockContentResolver mMockContentResolver; Loading Loading @@ -141,6 +144,11 @@ public class GattServiceTest { mAdapterService, Context.LOCATION_SERVICE, LocationManager.class); TestUtils.mockGetSystemService( mAdapterService, Context.ACTIVITY_SERVICE, ActivityManager.class); TestUtils.mockGetSystemService( mAdapterService, Context.COMPANION_DEVICE_SERVICE, CompanionDeviceManager.class, mCompanionDeviceManager); mBtCompanionManager = new CompanionManager(mAdapterService, null); doReturn(mBtCompanionManager).when(mAdapterService).getCompanionManager(); Loading