1*b7c941bbSAndroid Build Coastguard Worker /* 2*b7c941bbSAndroid Build Coastguard Worker * Copyright (C) 2024 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.app.UiAutomation; 20*b7c941bbSAndroid Build Coastguard Worker import android.bluetooth.BluetoothDevice; 21*b7c941bbSAndroid Build Coastguard Worker import android.bluetooth.OobData; 22*b7c941bbSAndroid Build Coastguard Worker 23*b7c941bbSAndroid Build Coastguard Worker import androidx.test.platform.app.InstrumentationRegistry; 24*b7c941bbSAndroid Build Coastguard Worker 25*b7c941bbSAndroid Build Coastguard Worker import org.json.JSONArray; 26*b7c941bbSAndroid Build Coastguard Worker import org.json.JSONException; 27*b7c941bbSAndroid Build Coastguard Worker import org.json.JSONObject; 28*b7c941bbSAndroid Build Coastguard Worker 29*b7c941bbSAndroid Build Coastguard Worker import java.lang.reflect.Method; 30*b7c941bbSAndroid Build Coastguard Worker import java.util.List; 31*b7c941bbSAndroid Build Coastguard Worker 32*b7c941bbSAndroid Build Coastguard Worker public class Utils { Utils()33*b7c941bbSAndroid Build Coastguard Worker private Utils() {} 34*b7c941bbSAndroid Build Coastguard Worker adoptShellPermission()35*b7c941bbSAndroid Build Coastguard Worker public static void adoptShellPermission() { 36*b7c941bbSAndroid Build Coastguard Worker UiAutomation uia = InstrumentationRegistry.getInstrumentation().getUiAutomation(); 37*b7c941bbSAndroid Build Coastguard Worker uia.adoptShellPermissionIdentity(); 38*b7c941bbSAndroid Build Coastguard Worker // Need to drop the UI Automation to allow other snippets to get access 39*b7c941bbSAndroid Build Coastguard Worker // to global UI automation. 40*b7c941bbSAndroid Build Coastguard Worker // Using reflection here since the method is not public. 41*b7c941bbSAndroid Build Coastguard Worker try { 42*b7c941bbSAndroid Build Coastguard Worker Class<?> cls = Class.forName("android.app.UiAutomation"); 43*b7c941bbSAndroid Build Coastguard Worker Method destroyMethod = cls.getDeclaredMethod("destroy"); 44*b7c941bbSAndroid Build Coastguard Worker destroyMethod.invoke(uia); 45*b7c941bbSAndroid Build Coastguard Worker } catch (ReflectiveOperationException e) { 46*b7c941bbSAndroid Build Coastguard Worker throw new IllegalStateException("Failed to cleaup Ui Automation", e); 47*b7c941bbSAndroid Build Coastguard Worker } 48*b7c941bbSAndroid Build Coastguard Worker } 49*b7c941bbSAndroid Build Coastguard Worker dropShellPermission()50*b7c941bbSAndroid Build Coastguard Worker public static void dropShellPermission() { 51*b7c941bbSAndroid Build Coastguard Worker UiAutomation uia = InstrumentationRegistry.getInstrumentation().getUiAutomation(); 52*b7c941bbSAndroid Build Coastguard Worker uia.dropShellPermissionIdentity(); 53*b7c941bbSAndroid Build Coastguard Worker // Need to drop the UI Automation to allow other snippets to get access 54*b7c941bbSAndroid Build Coastguard Worker // to global UI automation. 55*b7c941bbSAndroid Build Coastguard Worker // Using reflection here since the method is not public. 56*b7c941bbSAndroid Build Coastguard Worker try { 57*b7c941bbSAndroid Build Coastguard Worker Class<?> cls = Class.forName("android.app.UiAutomation"); 58*b7c941bbSAndroid Build Coastguard Worker Method destroyMethod = cls.getDeclaredMethod("destroy"); 59*b7c941bbSAndroid Build Coastguard Worker destroyMethod.invoke(uia); 60*b7c941bbSAndroid Build Coastguard Worker } catch (ReflectiveOperationException e) { 61*b7c941bbSAndroid Build Coastguard Worker throw new IllegalStateException("Failed to cleaup Ui Automation", e); 62*b7c941bbSAndroid Build Coastguard Worker } 63*b7c941bbSAndroid Build Coastguard Worker } 64*b7c941bbSAndroid Build Coastguard Worker convertJSONArrayToByteArray(JSONArray jArray)65*b7c941bbSAndroid Build Coastguard Worker private static byte[] convertJSONArrayToByteArray(JSONArray jArray) throws JSONException { 66*b7c941bbSAndroid Build Coastguard Worker if (jArray == null) { 67*b7c941bbSAndroid Build Coastguard Worker return null; 68*b7c941bbSAndroid Build Coastguard Worker } 69*b7c941bbSAndroid Build Coastguard Worker byte[] bArray = new byte[jArray.length()]; 70*b7c941bbSAndroid Build Coastguard Worker for (int i = 0; i < jArray.length(); i++) { 71*b7c941bbSAndroid Build Coastguard Worker bArray[i] = (byte) jArray.getInt(i); 72*b7c941bbSAndroid Build Coastguard Worker } 73*b7c941bbSAndroid Build Coastguard Worker return bArray; 74*b7c941bbSAndroid Build Coastguard Worker } 75*b7c941bbSAndroid Build Coastguard Worker convertByteArrayToJSONArray(byte[] array)76*b7c941bbSAndroid Build Coastguard Worker private static JSONArray convertByteArrayToJSONArray(byte[] array) throws JSONException { 77*b7c941bbSAndroid Build Coastguard Worker if (array == null) { 78*b7c941bbSAndroid Build Coastguard Worker return null; 79*b7c941bbSAndroid Build Coastguard Worker } 80*b7c941bbSAndroid Build Coastguard Worker return new JSONArray(array); 81*b7c941bbSAndroid Build Coastguard Worker } 82*b7c941bbSAndroid Build Coastguard Worker convertOobDataToJson(OobData oobData)83*b7c941bbSAndroid Build Coastguard Worker public static JSONObject convertOobDataToJson(OobData oobData) throws JSONException { 84*b7c941bbSAndroid Build Coastguard Worker if (oobData == null) return null; 85*b7c941bbSAndroid Build Coastguard Worker return new JSONObject() 86*b7c941bbSAndroid Build Coastguard Worker .put("device_address_with_type", 87*b7c941bbSAndroid Build Coastguard Worker convertByteArrayToJSONArray(oobData.getDeviceAddressWithType())) 88*b7c941bbSAndroid Build Coastguard Worker .put("confirmation_hash", 89*b7c941bbSAndroid Build Coastguard Worker convertByteArrayToJSONArray(oobData.getConfirmationHash())) 90*b7c941bbSAndroid Build Coastguard Worker .put("randomizer_hash", 91*b7c941bbSAndroid Build Coastguard Worker convertByteArrayToJSONArray(oobData.getRandomizerHash())) 92*b7c941bbSAndroid Build Coastguard Worker .put("device_name", convertByteArrayToJSONArray(oobData.getDeviceName())) 93*b7c941bbSAndroid Build Coastguard Worker .put("classic_length", 94*b7c941bbSAndroid Build Coastguard Worker convertByteArrayToJSONArray(oobData.getClassicLength())) 95*b7c941bbSAndroid Build Coastguard Worker .put("class_of_device", 96*b7c941bbSAndroid Build Coastguard Worker convertByteArrayToJSONArray(oobData.getClassOfDevice())) 97*b7c941bbSAndroid Build Coastguard Worker .put("le_temporary_key", 98*b7c941bbSAndroid Build Coastguard Worker convertByteArrayToJSONArray(oobData.getLeTemporaryKey())) 99*b7c941bbSAndroid Build Coastguard Worker .put("le_temporary_appearance", 100*b7c941bbSAndroid Build Coastguard Worker convertByteArrayToJSONArray(oobData.getLeAppearance())) 101*b7c941bbSAndroid Build Coastguard Worker .put("le_flags", oobData.getLeFlags()) 102*b7c941bbSAndroid Build Coastguard Worker .put("le_device_role", oobData.getLeDeviceRole()); 103*b7c941bbSAndroid Build Coastguard Worker } 104*b7c941bbSAndroid Build Coastguard Worker convertJsonToOobData(JSONObject jsonObj)105*b7c941bbSAndroid Build Coastguard Worker public static OobData convertJsonToOobData(JSONObject jsonObj) throws JSONException { 106*b7c941bbSAndroid Build Coastguard Worker if (jsonObj == null) return null; 107*b7c941bbSAndroid Build Coastguard Worker return new OobData.LeBuilder( 108*b7c941bbSAndroid Build Coastguard Worker convertJSONArrayToByteArray( 109*b7c941bbSAndroid Build Coastguard Worker jsonObj.getJSONArray("confirmation_hash")), 110*b7c941bbSAndroid Build Coastguard Worker convertJSONArrayToByteArray( 111*b7c941bbSAndroid Build Coastguard Worker jsonObj.getJSONArray("device_address_with_type")), 112*b7c941bbSAndroid Build Coastguard Worker jsonObj.getInt("le_device_role")) 113*b7c941bbSAndroid Build Coastguard Worker .setLeTemporaryKey(convertJSONArrayToByteArray( 114*b7c941bbSAndroid Build Coastguard Worker jsonObj.getJSONArray("le_temporary_key"))) 115*b7c941bbSAndroid Build Coastguard Worker .setRandomizerHash(convertJSONArrayToByteArray( 116*b7c941bbSAndroid Build Coastguard Worker jsonObj.getJSONArray("randomizer_hash"))) 117*b7c941bbSAndroid Build Coastguard Worker .setLeFlags(jsonObj.getInt("le_flags")) 118*b7c941bbSAndroid Build Coastguard Worker .setDeviceName(convertJSONArrayToByteArray( 119*b7c941bbSAndroid Build Coastguard Worker jsonObj.getJSONArray("device_name"))) 120*b7c941bbSAndroid Build Coastguard Worker .build(); 121*b7c941bbSAndroid Build Coastguard Worker } 122*b7c941bbSAndroid Build Coastguard Worker convertBtDeviceToJson(BluetoothDevice btDevice)123*b7c941bbSAndroid Build Coastguard Worker public static String convertBtDeviceToJson(BluetoothDevice btDevice) throws JSONException { 124*b7c941bbSAndroid Build Coastguard Worker if (btDevice == null) return null; 125*b7c941bbSAndroid Build Coastguard Worker return btDevice.getAddress(); 126*b7c941bbSAndroid Build Coastguard Worker } 127*b7c941bbSAndroid Build Coastguard Worker convertBtDevicesToJson(List<BluetoothDevice> btDevices)128*b7c941bbSAndroid Build Coastguard Worker public static JSONArray convertBtDevicesToJson(List<BluetoothDevice> btDevices) throws JSONException { 129*b7c941bbSAndroid Build Coastguard Worker if (btDevices == null) return null; 130*b7c941bbSAndroid Build Coastguard Worker JSONArray jsonArray = new JSONArray(); 131*b7c941bbSAndroid Build Coastguard Worker for (BluetoothDevice device: btDevices) { 132*b7c941bbSAndroid Build Coastguard Worker jsonArray.put(device.getAddress()); 133*b7c941bbSAndroid Build Coastguard Worker } 134*b7c941bbSAndroid Build Coastguard Worker return jsonArray; 135*b7c941bbSAndroid Build Coastguard Worker } 136*b7c941bbSAndroid Build Coastguard Worker } 137