• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 package com.android.bluetooth.btservice;
18 
19 import static java.util.Objects.requireNonNull;
20 
21 import android.bluetooth.BluetoothAdapter;
22 import android.bluetooth.BluetoothClass;
23 import android.bluetooth.BluetoothDevice;
24 import android.bluetooth.BluetoothQualityReport;
25 import android.bluetooth.BluetoothStatusCodes;
26 import android.util.Log;
27 
28 import com.android.bluetooth.Utils;
29 import com.android.internal.annotations.GuardedBy;
30 import com.android.internal.annotations.VisibleForTesting;
31 
32 /** Native interface to BQR */
33 public class BluetoothQualityReportNativeInterface {
34     private static final String TAG = BluetoothQualityReportNativeInterface.class.getSimpleName();
35 
36     @GuardedBy("INSTANCE_LOCK")
37     private static BluetoothQualityReportNativeInterface sInstance;
38 
39     private static final Object INSTANCE_LOCK = new Object();
40 
41     private final AdapterService mAdapterService;
42 
BluetoothQualityReportNativeInterface()43     private BluetoothQualityReportNativeInterface() {
44         mAdapterService = requireNonNull(AdapterService.getAdapterService());
45     }
46 
47     /** Get singleton instance. */
getInstance()48     public static BluetoothQualityReportNativeInterface getInstance() {
49         synchronized (INSTANCE_LOCK) {
50             if (sInstance == null) {
51                 sInstance = new BluetoothQualityReportNativeInterface();
52             }
53             return sInstance;
54         }
55     }
56 
57     /** Set singleton instance. */
58     @VisibleForTesting
setInstance(BluetoothQualityReportNativeInterface instance)59     static void setInstance(BluetoothQualityReportNativeInterface instance) {
60         synchronized (INSTANCE_LOCK) {
61             sInstance = instance;
62         }
63     }
64 
65     /**
66      * Initializes the native interface.
67      *
68      * <p>priorities to configure.
69      */
init()70     public void init() {
71         initNative();
72     }
73 
74     /** Cleanup the native interface. */
cleanup()75     public void cleanup() {
76         cleanupNative();
77     }
78 
79     /** Callback from the native stack back into the Java framework. */
bqrDeliver( byte[] remoteAddr, int lmpVer, int lmpSubVer, int manufacturerId, byte[] bqrRawData)80     private void bqrDeliver(
81             byte[] remoteAddr, int lmpVer, int lmpSubVer, int manufacturerId, byte[] bqrRawData) {
82         String remoteAddress = Utils.getAddressStringFromByte(remoteAddr);
83 
84         if (remoteAddress == null) {
85             Log.e(TAG, "bqrDeliver failed: remoteAddress is null");
86             return;
87         }
88         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
89         if (adapter == null) {
90             Log.e(TAG, "bqrDeliver failed: adapter is null");
91             return;
92         }
93 
94         BluetoothDevice device = adapter.getRemoteDevice(remoteAddress);
95         BluetoothClass remoteClass = new BluetoothClass(mAdapterService.getRemoteClass(device));
96         BluetoothQualityReport bqr;
97         try {
98             bqr =
99                     new BluetoothQualityReport.Builder(bqrRawData)
100                             .setRemoteAddress(remoteAddress)
101                             .setLmpVersion(lmpVer)
102                             .setLmpSubVersion(lmpSubVer)
103                             .setManufacturerId(manufacturerId)
104                             .setRemoteName(mAdapterService.getRemoteName(device))
105                             .setBluetoothClass(remoteClass)
106                             .build();
107             Log.i(TAG, bqr.toString());
108         } catch (Exception e) {
109             Log.e(TAG, "bqrDeliver failed: failed to create BluetoothQualityReport", e);
110             return;
111         }
112 
113         try {
114             int status = mAdapterService.bluetoothQualityReportReadyCallback(device, bqr);
115             if (status != BluetoothStatusCodes.SUCCESS) {
116                 Log.e(TAG, "bluetoothQualityReportReadyCallback failed, status: " + status);
117             }
118         } catch (Exception e) {
119             Log.e(TAG, "bqrDeliver failed: bluetoothQualityReportReadyCallback error", e);
120             return;
121         }
122     }
123 
124     // Native methods that call into the JNI interface
initNative()125     private native void initNative();
126 
cleanupNative()127     private native void cleanupNative();
128 }
129