1*b7c941bbSAndroid Build Coastguard Worker /* 2*b7c941bbSAndroid Build Coastguard Worker * Copyright 2023 The Android Open Source Project 3*b7c941bbSAndroid Build Coastguard Worker * 4*b7c941bbSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*b7c941bbSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*b7c941bbSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*b7c941bbSAndroid Build Coastguard Worker * 8*b7c941bbSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*b7c941bbSAndroid Build Coastguard Worker * 10*b7c941bbSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*b7c941bbSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*b7c941bbSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*b7c941bbSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*b7c941bbSAndroid Build Coastguard Worker * limitations under the License. 15*b7c941bbSAndroid Build Coastguard Worker */ 16*b7c941bbSAndroid Build Coastguard Worker 17*b7c941bbSAndroid Build Coastguard Worker package com.google.snippet.bluetooth; 18*b7c941bbSAndroid Build Coastguard Worker 19*b7c941bbSAndroid Build Coastguard Worker import android.bluetooth.BluetoothManager; 20*b7c941bbSAndroid Build Coastguard Worker import android.content.Context; 21*b7c941bbSAndroid Build Coastguard Worker 22*b7c941bbSAndroid Build Coastguard Worker import androidx.test.platform.app.InstrumentationRegistry; 23*b7c941bbSAndroid Build Coastguard Worker 24*b7c941bbSAndroid Build Coastguard Worker import com.google.android.mobly.snippet.Snippet; 25*b7c941bbSAndroid Build Coastguard Worker import com.google.android.mobly.snippet.rpc.Rpc; 26*b7c941bbSAndroid Build Coastguard Worker 27*b7c941bbSAndroid Build Coastguard Worker import org.json.JSONArray; 28*b7c941bbSAndroid Build Coastguard Worker import org.json.JSONException; 29*b7c941bbSAndroid Build Coastguard Worker import org.json.JSONObject; 30*b7c941bbSAndroid Build Coastguard Worker 31*b7c941bbSAndroid Build Coastguard Worker 32*b7c941bbSAndroid Build Coastguard Worker public class BluetoothGattMultiDevicesSnippet implements Snippet { 33*b7c941bbSAndroid Build Coastguard Worker private static final String TAG = "BluetoothGattMultiDevicesSnippet"; 34*b7c941bbSAndroid Build Coastguard Worker 35*b7c941bbSAndroid Build Coastguard Worker private BluetoothGattMultiDevicesServer mGattServer; 36*b7c941bbSAndroid Build Coastguard Worker private BluetoothGattMultiDevicesClient mGattClient; 37*b7c941bbSAndroid Build Coastguard Worker 38*b7c941bbSAndroid Build Coastguard Worker private Context mContext; 39*b7c941bbSAndroid Build Coastguard Worker private BluetoothManager mBluetoothManager; 40*b7c941bbSAndroid Build Coastguard Worker BluetoothGattMultiDevicesSnippet()41*b7c941bbSAndroid Build Coastguard Worker public BluetoothGattMultiDevicesSnippet() { 42*b7c941bbSAndroid Build Coastguard Worker mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 43*b7c941bbSAndroid Build Coastguard Worker mBluetoothManager = mContext.getSystemService(BluetoothManager.class); 44*b7c941bbSAndroid Build Coastguard Worker } 45*b7c941bbSAndroid Build Coastguard Worker 46*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Reset the state of client + server") reset()47*b7c941bbSAndroid Build Coastguard Worker public void reset() { 48*b7c941bbSAndroid Build Coastguard Worker mGattServer = new BluetoothGattMultiDevicesServer(mContext, mBluetoothManager); 49*b7c941bbSAndroid Build Coastguard Worker mGattClient = new BluetoothGattMultiDevicesClient(mContext, mBluetoothManager); 50*b7c941bbSAndroid Build Coastguard Worker } 51*b7c941bbSAndroid Build Coastguard Worker 52*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Creates Bluetooth GATT server with a given UUID and advertises it.") createAndAdvertiseServer(String uuid)53*b7c941bbSAndroid Build Coastguard Worker public void createAndAdvertiseServer(String uuid) { 54*b7c941bbSAndroid Build Coastguard Worker try { 55*b7c941bbSAndroid Build Coastguard Worker Utils.adoptShellPermission(); 56*b7c941bbSAndroid Build Coastguard Worker mGattServer.createAndAdvertiseServer(uuid); 57*b7c941bbSAndroid Build Coastguard Worker } finally { 58*b7c941bbSAndroid Build Coastguard Worker Utils.dropShellPermission(); 59*b7c941bbSAndroid Build Coastguard Worker } 60*b7c941bbSAndroid Build Coastguard Worker } 61*b7c941bbSAndroid Build Coastguard Worker 62*b7c941bbSAndroid Build Coastguard Worker @Rpc( 63*b7c941bbSAndroid Build Coastguard Worker description = 64*b7c941bbSAndroid Build Coastguard Worker "Creates Bluetooth GATT server with a given UUID and ties it to an" 65*b7c941bbSAndroid Build Coastguard Worker + " advertisement.") createAndAdvertiseIsolatedServer(String uuid)66*b7c941bbSAndroid Build Coastguard Worker public void createAndAdvertiseIsolatedServer(String uuid) { 67*b7c941bbSAndroid Build Coastguard Worker try { 68*b7c941bbSAndroid Build Coastguard Worker Utils.adoptShellPermission(); 69*b7c941bbSAndroid Build Coastguard Worker mGattServer.createAndAdvertiseIsolatedServer(uuid); 70*b7c941bbSAndroid Build Coastguard Worker } finally { 71*b7c941bbSAndroid Build Coastguard Worker Utils.dropShellPermission(); 72*b7c941bbSAndroid Build Coastguard Worker } 73*b7c941bbSAndroid Build Coastguard Worker } 74*b7c941bbSAndroid Build Coastguard Worker 75*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Connect to the peer device advertising the specified UUID") connectGatt(String uuid)76*b7c941bbSAndroid Build Coastguard Worker public String connectGatt(String uuid) throws JSONException { 77*b7c941bbSAndroid Build Coastguard Worker try { 78*b7c941bbSAndroid Build Coastguard Worker Utils.adoptShellPermission(); 79*b7c941bbSAndroid Build Coastguard Worker return Utils.convertBtDeviceToJson(mGattClient.connect(uuid)); 80*b7c941bbSAndroid Build Coastguard Worker } finally { 81*b7c941bbSAndroid Build Coastguard Worker Utils.dropShellPermission(); 82*b7c941bbSAndroid Build Coastguard Worker } 83*b7c941bbSAndroid Build Coastguard Worker } 84*b7c941bbSAndroid Build Coastguard Worker 85*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Disconnect to the peer device advertising the specified UUID") disconnectGatt(String uuid)86*b7c941bbSAndroid Build Coastguard Worker public boolean disconnectGatt(String uuid) throws JSONException { 87*b7c941bbSAndroid Build Coastguard Worker try { 88*b7c941bbSAndroid Build Coastguard Worker Utils.adoptShellPermission(); 89*b7c941bbSAndroid Build Coastguard Worker return mGattClient.disconnect(uuid); 90*b7c941bbSAndroid Build Coastguard Worker } finally { 91*b7c941bbSAndroid Build Coastguard Worker Utils.dropShellPermission(); 92*b7c941bbSAndroid Build Coastguard Worker } 93*b7c941bbSAndroid Build Coastguard Worker } 94*b7c941bbSAndroid Build Coastguard Worker 95*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Get all the devices connected to the GATT server") getConnectedDevices()96*b7c941bbSAndroid Build Coastguard Worker public JSONArray getConnectedDevices() throws JSONException { 97*b7c941bbSAndroid Build Coastguard Worker try { 98*b7c941bbSAndroid Build Coastguard Worker Utils.adoptShellPermission(); 99*b7c941bbSAndroid Build Coastguard Worker return Utils.convertBtDevicesToJson(mGattServer.getConnectedDevices()); 100*b7c941bbSAndroid Build Coastguard Worker } finally { 101*b7c941bbSAndroid Build Coastguard Worker Utils.dropShellPermission(); 102*b7c941bbSAndroid Build Coastguard Worker } 103*b7c941bbSAndroid Build Coastguard Worker } 104*b7c941bbSAndroid Build Coastguard Worker 105*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Generate local OOB data to used for bonding with the server") generateServerLocalOobData()106*b7c941bbSAndroid Build Coastguard Worker public JSONObject generateServerLocalOobData() throws JSONException { 107*b7c941bbSAndroid Build Coastguard Worker try { 108*b7c941bbSAndroid Build Coastguard Worker Utils.adoptShellPermission(); 109*b7c941bbSAndroid Build Coastguard Worker return Utils.convertOobDataToJson(mGattServer.generateLocalOObData()); 110*b7c941bbSAndroid Build Coastguard Worker } finally { 111*b7c941bbSAndroid Build Coastguard Worker Utils.dropShellPermission(); 112*b7c941bbSAndroid Build Coastguard Worker } 113*b7c941bbSAndroid Build Coastguard Worker } 114*b7c941bbSAndroid Build Coastguard Worker 115*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Create a bond with the server using local OOB data generated on the server") createBondOob(String uuid, JSONObject jsonObject)116*b7c941bbSAndroid Build Coastguard Worker public String createBondOob(String uuid, JSONObject jsonObject) throws JSONException { 117*b7c941bbSAndroid Build Coastguard Worker try { 118*b7c941bbSAndroid Build Coastguard Worker Utils.adoptShellPermission(); 119*b7c941bbSAndroid Build Coastguard Worker return Utils.convertBtDeviceToJson(mGattClient.createBondOob( 120*b7c941bbSAndroid Build Coastguard Worker uuid, Utils.convertJsonToOobData(jsonObject))); 121*b7c941bbSAndroid Build Coastguard Worker } finally { 122*b7c941bbSAndroid Build Coastguard Worker Utils.dropShellPermission(); 123*b7c941bbSAndroid Build Coastguard Worker } 124*b7c941bbSAndroid Build Coastguard Worker } 125*b7c941bbSAndroid Build Coastguard Worker 126*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Create a bond with the server using local OOB data generated on the server") removeBond(String uuid)127*b7c941bbSAndroid Build Coastguard Worker public boolean removeBond(String uuid) { 128*b7c941bbSAndroid Build Coastguard Worker try { 129*b7c941bbSAndroid Build Coastguard Worker Utils.adoptShellPermission(); 130*b7c941bbSAndroid Build Coastguard Worker return mGattClient.removeBond(uuid); 131*b7c941bbSAndroid Build Coastguard Worker } finally { 132*b7c941bbSAndroid Build Coastguard Worker Utils.dropShellPermission(); 133*b7c941bbSAndroid Build Coastguard Worker } 134*b7c941bbSAndroid Build Coastguard Worker } 135*b7c941bbSAndroid Build Coastguard Worker 136*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Enables Bluetooth") enableBluetooth()137*b7c941bbSAndroid Build Coastguard Worker public void enableBluetooth() { 138*b7c941bbSAndroid Build Coastguard Worker try { 139*b7c941bbSAndroid Build Coastguard Worker Utils.adoptShellPermission(); 140*b7c941bbSAndroid Build Coastguard Worker mBluetoothManager.getAdapter().enable(); 141*b7c941bbSAndroid Build Coastguard Worker } finally { 142*b7c941bbSAndroid Build Coastguard Worker Utils.dropShellPermission(); 143*b7c941bbSAndroid Build Coastguard Worker } 144*b7c941bbSAndroid Build Coastguard Worker } 145*b7c941bbSAndroid Build Coastguard Worker 146*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Disable Bluetooth") disableBluetooth()147*b7c941bbSAndroid Build Coastguard Worker public void disableBluetooth() { 148*b7c941bbSAndroid Build Coastguard Worker try { 149*b7c941bbSAndroid Build Coastguard Worker Utils.adoptShellPermission(); 150*b7c941bbSAndroid Build Coastguard Worker mBluetoothManager.getAdapter().disable(); 151*b7c941bbSAndroid Build Coastguard Worker } finally { 152*b7c941bbSAndroid Build Coastguard Worker Utils.dropShellPermission(); 153*b7c941bbSAndroid Build Coastguard Worker } 154*b7c941bbSAndroid Build Coastguard Worker } 155*b7c941bbSAndroid Build Coastguard Worker 156*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Checks Bluetooth state") isBluetoothOn()157*b7c941bbSAndroid Build Coastguard Worker public boolean isBluetoothOn() { 158*b7c941bbSAndroid Build Coastguard Worker return mBluetoothManager.getAdapter().isEnabled(); 159*b7c941bbSAndroid Build Coastguard Worker } 160*b7c941bbSAndroid Build Coastguard Worker 161*b7c941bbSAndroid Build Coastguard Worker @Rpc(description = "Whether the connected peer has a service of the given UUID") containsService(String uuid)162*b7c941bbSAndroid Build Coastguard Worker public boolean containsService(String uuid) { 163*b7c941bbSAndroid Build Coastguard Worker try { 164*b7c941bbSAndroid Build Coastguard Worker Utils.adoptShellPermission(); 165*b7c941bbSAndroid Build Coastguard Worker return mGattClient.containsService(uuid); 166*b7c941bbSAndroid Build Coastguard Worker } finally { 167*b7c941bbSAndroid Build Coastguard Worker Utils.dropShellPermission(); 168*b7c941bbSAndroid Build Coastguard Worker } 169*b7c941bbSAndroid Build Coastguard Worker } 170*b7c941bbSAndroid Build Coastguard Worker } 171