aboutsummaryrefslogtreecommitdiff
path: root/le_audio/packages/apps/Bluetooth/src/com/android/bluetooth/cc/CCNativeInterface.java
diff options
context:
space:
mode:
Diffstat (limited to 'le_audio/packages/apps/Bluetooth/src/com/android/bluetooth/cc/CCNativeInterface.java')
-rw-r--r--le_audio/packages/apps/Bluetooth/src/com/android/bluetooth/cc/CCNativeInterface.java255
1 files changed, 255 insertions, 0 deletions
diff --git a/le_audio/packages/apps/Bluetooth/src/com/android/bluetooth/cc/CCNativeInterface.java b/le_audio/packages/apps/Bluetooth/src/com/android/bluetooth/cc/CCNativeInterface.java
new file mode 100644
index 000000000..1e93c62fc
--- /dev/null
+++ b/le_audio/packages/apps/Bluetooth/src/com/android/bluetooth/cc/CCNativeInterface.java
@@ -0,0 +1,255 @@
+/*
+ *Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Defines the native interface that is used by state machine/service to
+ * send or receive messages from the native stack. This file is registered
+ * for the native methods in the corresponding JNI C++ file.
+ */
+package com.android.bluetooth.cc;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.util.Log;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.android.bluetooth.Utils;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Ccp Native Interface to/from JNI.
+ */
+public class CCNativeInterface {
+ private static final String TAG = "CCNativeInterface";
+ private static final boolean DBG = true;
+ private BluetoothAdapter mAdapter;
+
+ @GuardedBy("INSTANCE_LOCK")
+ private static CCNativeInterface sInstance;
+ private static final Object INSTANCE_LOCK = new Object();
+
+ static {
+ classInitNative();
+ }
+
+ private CCNativeInterface() {
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (mAdapter == null) {
+ Log.w(TAG, "No Bluetooth Adapter Available");
+ }
+ }
+
+ /**
+ * This class is a singleton because native library should only be loaded once
+ *
+ * @return default instance
+ */
+ public static CCNativeInterface getInstance() {
+ synchronized (INSTANCE_LOCK) {
+ if (sInstance == null) {
+ sInstance = new CCNativeInterface();
+ }
+ return sInstance;
+ }
+ }
+
+ /**
+ * Initialize native stack
+ *
+ * @param ccsClients maximum number of CCS clients that can be connected simultaneously
+ * @param inbandRingingEnabled whether in-band ringing is enabled on this AG
+ */
+ @VisibleForTesting
+ public void init(int maxCcsClients, boolean inbandRingingEnabled) {
+ initializeNative("00008fd1-0000-1000-8000-00805F9B34FB", maxCcsClients, inbandRingingEnabled);
+ }
+
+ /**
+ * Cleanup the native interface.
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public void cleanup() {
+ cleanupNative();
+ }
+
+ /**
+ * Disconnects Call control from a remote device.
+ *
+ * @param device the remote device
+ * @return true on success, otherwise false.
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean disconnect(BluetoothDevice device) {
+ return disconnectNative(getByteAddress(device));
+ }
+ /**
+ * update CC optional supported feature
+ * @param feature
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean callControlOptionalFeatures(int feature) {
+ return callControlPointOpcodeSupportedNative(feature);
+ }
+
+ /**
+ * Sets the CC call state
+ * @param state
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean callState(ArrayList<CallControlState> callList) {
+ int len = callList.size();
+ byte[] cStateListBytes = new byte[len*3];
+ for (int i=0; i<len; i++) {
+ cStateListBytes[3*i+0] = (byte) callList.get(i).mIndex;
+ cStateListBytes[3*i+1] = (byte) CCHalConstants.getCCsCallState(callList.get(i).mState);
+ cStateListBytes[3*i+2] = (byte) callList.get(i).mFlags;
+ }
+ return callStateNative(len, cStateListBytes);
+ }
+
+ /**
+ * update CC Bearer name
+ * @param Bearer name
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean updateBearerProviderName(String name) {
+ return updateBearerNameNative(name);
+ }
+
+ /**
+ * update CC Bearer technology type
+ * @param Bearer technology
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean updateBearerTechnology(int tech_type) {
+ return updateBearerTechnologyNative(tech_type);
+
+ }
+
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean updateStatusFlags(int value) {
+ return updateStatusFlagsNative(value);
+ }
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean updateSignalStrength(int signal_value) {
+ return updateSignalStatusNative(signal_value);
+ }
+
+
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean updateIncomingCall(int index, String uri) {
+ updateIncomingCallNative(index, uri);
+ return true;
+ }
+
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean updateSupportedBearerList(String supportedBearers) {
+ return updateSupportedBearerListNative(supportedBearers);
+ }
+
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean callControlResponse(int op, int index, int status, BluetoothDevice device) {
+ return callControlResponseNative(op, index, status, getByteAddress(device));
+ }
+
+ /**
+ * update active device
+ * @param device
+ * @param setId
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean setActiveDevice(BluetoothDevice device, int setId) {
+ return setActiveDeviceNative(setId, getByteAddress(device));
+ }
+ /**
+ * Sets call content control id
+ * @param ccid
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean contentControlId(int ccid) {
+
+ return contentControlIdNative(ccid);
+ }
+
+ private BluetoothDevice getDevice(byte[] address) {
+ return mAdapter.getRemoteDevice(address);
+ }
+
+ private byte[] getByteAddress(BluetoothDevice device) {
+ if (device == null) {
+ return Utils.getBytesFromAddress("00:00:00:00:00:00");
+ }
+ return Utils.getBytesFromAddress(device.getAddress());
+ }
+
+ // Callbacks from the native stack back into the Java framework.
+ private void callControlInitializedCallback(int state) {
+ if (DBG) {
+ Log.d(TAG, "CallControlInitializedCallback: " + state);
+ }
+
+ CCService service = CCService.getCCService();
+ if (service != null) {
+ service.onCallControlInitialized(state);
+ }
+ }
+
+ private void onConnectionStateChanged(int state, byte[] address) {
+ if (DBG) {
+ Log.d(TAG, "OnConnectionStateChanged: " + state);
+ }
+ BluetoothDevice device = getDevice(address);
+
+ CCService service = CCService.getCCService();
+ if (service != null)
+ service.onConnectionStateChanged(device, state);
+ }
+
+ private void callControlPointChangedRequest(int op, int[]call_indices, int count, byte[] dialNumber, byte[] address) {
+ BluetoothDevice device = getDevice(address);
+ String dialUri = new String(dialNumber, StandardCharsets.UTF_8);
+ if (DBG) {
+ Log.d(TAG, "CallControlPointChangedRequest: " + op + "dialNumber: " + dialUri);
+ }
+ CCService service = CCService.getCCService();
+ if (service != null)
+ service.onCallControlPointChangedRequest(op, call_indices, count, dialUri, device);
+ }
+
+ // Native methods that call into the JNI interface
+ private static native void classInitNative();
+ private native void initializeNative(String uuid, int max_ccs_clients, boolean inbandRingingEnabled);
+ private native void cleanupNative();
+ private native boolean callControlPointOpcodeSupportedNative(int feature);
+ private native boolean callStateNative(int len, byte[] callStateList);
+ private native boolean updateBearerNameNative(String providerName);
+ private native boolean updateBearerTechnologyNative(int tech_type);
+ private native boolean updateSignalStatusNative(int signal);
+ private native boolean updateStatusFlagsNative(int value);
+ private native boolean setActiveDeviceNative(int setId, byte[] address);
+ private native boolean contentControlIdNative(int ccid);
+ private native boolean disconnectNative(byte[] address);
+ private native boolean callControlResponseNative(int op, int index, int status, byte[] address);
+ private native boolean updateSupportedBearerListNative(String supportedBearers);
+ private native boolean updateIncomingCallNative(int index, String uri);
+}