Add Framework openGattServer
Bug: 267203732
Test: build
Change-Id: Ied81b7a0f33e585466250503f0167a1eaef0f2c4
diff --git a/bluetooth/integration-tests/testapp/src/main/AndroidManifest.xml b/bluetooth/integration-tests/testapp/src/main/AndroidManifest.xml
index 1f1625b..4fd7629 100644
--- a/bluetooth/integration-tests/testapp/src/main/AndroidManifest.xml
+++ b/bluetooth/integration-tests/testapp/src/main/AndroidManifest.xml
@@ -21,7 +21,8 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
- <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
+ <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+ <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
</manifest>
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/MainActivity.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/MainActivity.kt
index 3066bdc..9f655fb 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/MainActivity.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/MainActivity.kt
@@ -66,6 +66,7 @@
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.BLUETOOTH_ADVERTISE,
+ Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.BLUETOOTH_SCAN,
)
)
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/framework/FwkFragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/framework/FwkFragment.kt
index d066bbc..46e8e17 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/framework/FwkFragment.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/framework/FwkFragment.kt
@@ -17,6 +17,12 @@
package androidx.bluetooth.integration.testapp.ui.framework
import android.annotation.SuppressLint
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothGattCharacteristic
+import android.bluetooth.BluetoothGattDescriptor
+import android.bluetooth.BluetoothGattServer
+import android.bluetooth.BluetoothGattServerCallback
+import android.bluetooth.BluetoothGattService
import android.bluetooth.BluetoothManager
import android.bluetooth.le.AdvertiseCallback
import android.bluetooth.le.AdvertiseData
@@ -80,8 +86,10 @@
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
- Log.d(TAG, "onCreateView() called with: inflater = $inflater, " +
- "container = $container, savedInstanceState = $savedInstanceState")
+ Log.d(
+ TAG, "onCreateView() called with: inflater = $inflater, " +
+ "container = $container, savedInstanceState = $savedInstanceState"
+ )
fwkViewModel = ViewModelProvider(this)[FwkViewModel::class.java]
_binding = FragmentFwkBinding.inflate(inflater, container, false)
@@ -99,11 +107,19 @@
if (isChecked) startAdvertise()
else stopAdvertise()
}
+
+ binding.switchGattServer.setOnCheckedChangeListener { _, isChecked ->
+ if (isChecked) openGattServer()
+ else closeGattServer()
+ }
}
+ // Permissions are handled by MainActivity requestBluetoothPermissions
+ @SuppressLint("MissingPermission")
override fun onDestroyView() {
super.onDestroyView()
_binding = null
+ bluetoothGattServer?.close()
}
// Permissions are handled by MainActivity requestBluetoothPermissions
@@ -170,4 +186,154 @@
bleAdvertiser?.stopAdvertising(advertiseCallback)
}
+
+ private var bluetoothGattServer: BluetoothGattServer? = null
+
+ // Permissions are handled by MainActivity requestBluetoothPermissions
+ @SuppressLint("MissingPermission")
+ private fun openGattServer() {
+ Log.d(TAG, "openGattServer() called")
+
+ val bluetoothManager =
+ context?.getSystemService(Context.BLUETOOTH_SERVICE) as? BluetoothManager
+
+ bluetoothGattServer = bluetoothManager?.openGattServer(
+ requireContext(),
+ object : BluetoothGattServerCallback() {
+ override fun onConnectionStateChange(
+ device: BluetoothDevice?,
+ status: Int,
+ newState: Int
+ ) {
+ Log.d(
+ TAG,
+ "onConnectionStateChange() called with: device = $device" +
+ ", status = $status, newState = $newState"
+ )
+ }
+
+ override fun onServiceAdded(status: Int, service: BluetoothGattService?) {
+ Log.d(TAG, "onServiceAdded() called with: status = $status, service = $service")
+ }
+
+ override fun onCharacteristicReadRequest(
+ device: BluetoothDevice?,
+ requestId: Int,
+ offset: Int,
+ characteristic: BluetoothGattCharacteristic?
+ ) {
+ Log.d(
+ TAG,
+ "onCharacteristicReadRequest() called with: device = $device" +
+ ", requestId = $requestId, offset = $offset" +
+ ", characteristic = $characteristic"
+ )
+ }
+
+ override fun onCharacteristicWriteRequest(
+ device: BluetoothDevice?,
+ requestId: Int,
+ characteristic: BluetoothGattCharacteristic?,
+ preparedWrite: Boolean,
+ responseNeeded: Boolean,
+ offset: Int,
+ value: ByteArray?
+ ) {
+ Log.d(
+ TAG,
+ "onCharacteristicWriteRequest() called with: device = $device" +
+ ", requestId = $requestId, characteristic = $characteristic" +
+ ", preparedWrite = $preparedWrite, responseNeeded = $responseNeeded" +
+ ", offset = $offset, value = $value"
+ )
+ }
+
+ override fun onDescriptorReadRequest(
+ device: BluetoothDevice?,
+ requestId: Int,
+ offset: Int,
+ descriptor: BluetoothGattDescriptor?
+ ) {
+ Log.d(
+ TAG,
+ "onDescriptorReadRequest() called with: device = $device" +
+ ", requestId = $requestId, offset = $offset, descriptor = $descriptor"
+ )
+ }
+
+ override fun onDescriptorWriteRequest(
+ device: BluetoothDevice?,
+ requestId: Int,
+ descriptor: BluetoothGattDescriptor?,
+ preparedWrite: Boolean,
+ responseNeeded: Boolean,
+ offset: Int,
+ value: ByteArray?
+ ) {
+ Log.d(
+ TAG,
+ "onDescriptorWriteRequest() called with: device = $device" +
+ ", requestId = $requestId, descriptor = $descriptor" +
+ ", preparedWrite = $preparedWrite, responseNeeded = $responseNeeded" +
+ ", offset = $offset, value = $value"
+ )
+ }
+
+ override fun onExecuteWrite(
+ device: BluetoothDevice?,
+ requestId: Int,
+ execute: Boolean
+ ) {
+ Log.d(
+ TAG,
+ "onExecuteWrite() called with: device = $device, requestId = $requestId" +
+ ", execute = $execute"
+ )
+ }
+
+ override fun onNotificationSent(device: BluetoothDevice?, status: Int) {
+ Log.d(
+ TAG,
+ "onNotificationSent() called with: device = $device, status = $status"
+ )
+ }
+
+ override fun onMtuChanged(device: BluetoothDevice?, mtu: Int) {
+ Log.d(TAG, "onMtuChanged() called with: device = $device, mtu = $mtu")
+ }
+
+ override fun onPhyUpdate(
+ device: BluetoothDevice?,
+ txPhy: Int,
+ rxPhy: Int,
+ status: Int
+ ) {
+ Log.d(
+ TAG, "onPhyUpdate() called with: device = $device, txPhy = $txPhy" +
+ ", rxPhy = $rxPhy, status = $status"
+ )
+ }
+
+ override fun onPhyRead(
+ device: BluetoothDevice?,
+ txPhy: Int,
+ rxPhy: Int,
+ status: Int
+ ) {
+ Log.d(
+ TAG,
+ "onPhyRead() called with: device = $device, txPhy = $txPhy" +
+ ", rxPhy = $rxPhy, status = $status"
+ )
+ }
+ })
+ }
+
+ // Permissions are handled by MainActivity requestBluetoothPermissions
+ @SuppressLint("MissingPermission")
+ private fun closeGattServer() {
+ Log.d(TAG, "closeGattServer() called")
+
+ bluetoothGattServer?.close()
+ }
}
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/activity_main.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/activity_main.xml
index 4bdca3c..5d9372f 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/layout/activity_main.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/activity_main.xml
@@ -21,7 +21,6 @@
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingTop="?attr/actionBarSize"
tools:context=".MainActivity">
<com.google.android.material.bottomnavigation.BottomNavigationView
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_fwk.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_fwk.xml
index 6a72bf2..48c20bf 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_fwk.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_fwk.xml
@@ -20,27 +20,36 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:padding="16dp"
tools:context=".ui.framework.FwkFragment">
- <androidx.appcompat.widget.SwitchCompat
- android:id="@+id/switch_advertise"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/advertise_using_fwk"
- android:layout_marginBottom="16dp"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/button_scan"
- app:layout_constraintEnd_toEndOf="parent" />
-
<Button
android:id="@+id/button_scan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
+ android:layout_marginTop="16dp"
android:text="@string/scan_using_fwk"
- app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent" />
+ app:layout_constraintTop_toTopOf="parent" />
+
+ <androidx.appcompat.widget.SwitchCompat
+ android:id="@+id/switch_advertise"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:text="@string/advertise_using_fwk"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/button_scan" />
+
+ <androidx.appcompat.widget.SwitchCompat
+ android:id="@+id/switch_gatt_server"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:text="@string/open_gatt_server_using_fwk"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/switch_advertise" />
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml b/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
index 170c6a7..913a1bb 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
@@ -27,4 +27,8 @@
<string name="advertise_using_fwk">Advertise using Framework Bluetooth APIs</string>
<string name="advertise_using_btx">Advertise using BluetoothX APIs</string>
<string name="advertise_start_message">Advertise started</string>
+
+ <string name="open_gatt_server_using_fwk">Open GATT Server using Framework Bluetooth APIs</string>
+ <string name="open_gatt_server_using_btx">Open GATT Server using BluetoothX APIs</string>
+ <string name="gatt_server_open">GATT Server open</string>
</resources>