1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Defines the native interface that is used by state machine/service to 19 * send or receive messages from the native stack. This file is registered 20 * for the native methods in the corresponding JNI C++ file. 21 */ 22 package com.android.bluetooth.a2dp; 23 24 import static java.util.Objects.requireNonNull; 25 26 import android.annotation.NonNull; 27 import android.bluetooth.BluetoothCodecConfig; 28 import android.bluetooth.BluetoothCodecType; 29 import android.bluetooth.BluetoothDevice; 30 31 import com.android.bluetooth.Utils; 32 import com.android.internal.annotations.VisibleForTesting; 33 34 import java.lang.annotation.Native; 35 import java.util.Arrays; 36 import java.util.List; 37 38 /** A2DP Native Interface to/from JNI. */ 39 public class A2dpNativeInterface { 40 private static final String TAG = A2dpNativeInterface.class.getSimpleName(); 41 42 @Native private final A2dpNativeCallback mNativeCallback; 43 44 private BluetoothCodecType[] mSupportedCodecTypes; 45 46 @VisibleForTesting A2dpNativeInterface(@onNull A2dpNativeCallback nativeCallback)47 A2dpNativeInterface(@NonNull A2dpNativeCallback nativeCallback) { 48 mNativeCallback = requireNonNull(nativeCallback); 49 } 50 51 /** 52 * Initializes the native interface. 53 * 54 * @param maxConnectedAudioDevices maximum number of A2DP Sink devices that can be connected 55 * simultaneously 56 * @param codecConfigPriorities an array with the codec configuration priorities to configure. 57 */ init( int maxConnectedAudioDevices, BluetoothCodecConfig[] codecConfigPriorities, BluetoothCodecConfig[] codecConfigOffloading)58 public void init( 59 int maxConnectedAudioDevices, 60 BluetoothCodecConfig[] codecConfigPriorities, 61 BluetoothCodecConfig[] codecConfigOffloading) { 62 initNative(maxConnectedAudioDevices, codecConfigPriorities, codecConfigOffloading); 63 } 64 65 /** Cleanup the native interface. */ cleanup()66 public void cleanup() { 67 cleanupNative(); 68 } 69 70 /** Returns the list of locally supported codec types. */ getSupportedCodecTypes()71 public List<BluetoothCodecType> getSupportedCodecTypes() { 72 if (mSupportedCodecTypes == null) { 73 mSupportedCodecTypes = getSupportedCodecTypesNative(); 74 } 75 return Arrays.asList(mSupportedCodecTypes); 76 } 77 78 /** 79 * Initiates A2DP connection to a remote device. 80 * 81 * @param device the remote device 82 * @return true on success, otherwise false. 83 */ connectA2dp(BluetoothDevice device)84 public boolean connectA2dp(BluetoothDevice device) { 85 return connectA2dpNative(getByteAddress(device)); 86 } 87 88 /** 89 * Disconnects A2DP from a remote device. 90 * 91 * @param device the remote device 92 * @return true on success, otherwise false. 93 */ disconnectA2dp(BluetoothDevice device)94 public boolean disconnectA2dp(BluetoothDevice device) { 95 return disconnectA2dpNative(getByteAddress(device)); 96 } 97 98 /** 99 * Sets a connected A2DP remote device to silence mode. 100 * 101 * @param device the remote device 102 * @return true on success, otherwise false. 103 */ setSilenceDevice(BluetoothDevice device, boolean silence)104 public boolean setSilenceDevice(BluetoothDevice device, boolean silence) { 105 return setSilenceDeviceNative(getByteAddress(device), silence); 106 } 107 108 /** 109 * Sets a connected A2DP remote device as active. 110 * 111 * @param device the remote device 112 * @return true on success, otherwise false. 113 */ setActiveDevice(BluetoothDevice device)114 public boolean setActiveDevice(BluetoothDevice device) { 115 return setActiveDeviceNative(getByteAddress(device)); 116 } 117 118 /** 119 * Sets the codec configuration preferences. 120 * 121 * @param device the remote Bluetooth device 122 * @param codecConfigArray an array with the codec configurations to configure. 123 * @return true on success, otherwise false. 124 */ setCodecConfigPreference( BluetoothDevice device, BluetoothCodecConfig[] codecConfigArray)125 public boolean setCodecConfigPreference( 126 BluetoothDevice device, BluetoothCodecConfig[] codecConfigArray) { 127 return setCodecConfigPreferenceNative(getByteAddress(device), codecConfigArray); 128 } 129 getByteAddress(BluetoothDevice device)130 private static byte[] getByteAddress(BluetoothDevice device) { 131 if (device == null) { 132 return Utils.getBytesFromAddress("00:00:00:00:00:00"); 133 } 134 return Utils.getByteBrEdrAddress(device); 135 } 136 initNative( int maxConnectedAudioDevices, BluetoothCodecConfig[] codecConfigPriorities, BluetoothCodecConfig[] codecConfigOffloading)137 private native void initNative( 138 int maxConnectedAudioDevices, 139 BluetoothCodecConfig[] codecConfigPriorities, 140 BluetoothCodecConfig[] codecConfigOffloading); 141 cleanupNative()142 private native void cleanupNative(); 143 getSupportedCodecTypesNative()144 private native BluetoothCodecType[] getSupportedCodecTypesNative(); 145 connectA2dpNative(byte[] address)146 private native boolean connectA2dpNative(byte[] address); 147 disconnectA2dpNative(byte[] address)148 private native boolean disconnectA2dpNative(byte[] address); 149 setSilenceDeviceNative(byte[] address, boolean silence)150 private native boolean setSilenceDeviceNative(byte[] address, boolean silence); 151 setActiveDeviceNative(byte[] address)152 private native boolean setActiveDeviceNative(byte[] address); 153 setCodecConfigPreferenceNative( byte[] address, BluetoothCodecConfig[] codecConfigArray)154 private native boolean setCodecConfigPreferenceNative( 155 byte[] address, BluetoothCodecConfig[] codecConfigArray); 156 } 157