1 /* 2 * Copyright (c) 2022 The Android Open Source Project 3 * Copyright (c) 2020 The Linux Foundation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.android.bluetooth.btservice; 19 20 import android.util.Log; 21 22 /** 23 * APIs of interoperability workaround utilities. 24 * These APIs will call stack layer's interop APIs of interop.cc to do matching 25 * or entry adding/removing. 26 */ 27 public class InteropUtil { 28 private static final String TAG = "InteropUtil"; 29 30 /** 31 * Add interop feature from device/include/interop.h to below InteropFeature if 32 * this feature needs to be matched at java layer. Feature's name will be passed to 33 * stack layer to do matching, so make sure that the added feature's name is exactly 34 * same as that in device/include/interop.h. 35 */ 36 public enum InteropFeature { 37 INTEROP_NOT_UPDATE_AVRCP_PAUSED_TO_REMOTE, 38 INTEROP_PHONE_POLICY_INCREASED_DELAY_CONNECT_OTHER_PROFILES, 39 INTEROP_PHONE_POLICY_REDUCED_DELAY_CONNECT_OTHER_PROFILES, 40 INTEROP_HFP_FAKE_INCOMING_CALL_INDICATOR, 41 INTEROP_HFP_SEND_CALL_INDICATORS_BACK_TO_BACK, 42 INTEROP_SETUP_SCO_WITH_NO_DELAY_AFTER_SLC_DURING_CALL, 43 INTEROP_RETRY_SCO_AFTER_REMOTE_REJECT_SCO, 44 INTEROP_ADV_PBAP_VER_1_2; 45 } 46 47 /** 48 * Check if a given address matches a known interoperability workaround 49 * identified by the interop feature. 50 * 51 * @param feature a given interop feature defined in {@link InteropFeature}. 52 * @param address a given address to be matched. 53 * @return true if matched, false otherwise. 54 */ interopMatchAddr(InteropFeature feature, String address)55 public static boolean interopMatchAddr(InteropFeature feature, String address) { 56 AdapterService adapterService = AdapterService.getAdapterService(); 57 if (adapterService == null) { 58 Log.d(TAG, "interopMatchAddr: feature=" + feature.name() 59 + ", adapterService is null or vendor intf is not enabled"); 60 return false; 61 } 62 63 Log.d(TAG, "interopMatchAddr: feature=" + feature.name() + ", address=" + address); 64 if (address == null) { 65 return false; 66 } 67 68 boolean matched = adapterService.interopMatchAddr(feature, address); 69 Log.d(TAG, "interopMatchAddr: matched=" + matched); 70 return matched; 71 } 72 73 /** 74 * Check if a given name matches a known interoperability workaround 75 * identified by the interop feature. 76 * 77 * @param feature a given interop feature defined in {@link InteropFeature}. 78 * @param name a given name to be matched. 79 * @return true if matched, false otherwise. 80 */ interopMatchName(InteropFeature feature, String name)81 public static boolean interopMatchName(InteropFeature feature, String name) { 82 AdapterService adapterService = AdapterService.getAdapterService(); 83 if (adapterService == null) { 84 Log.d(TAG, "interopMatchName: feature=" + feature.name() 85 + ", adapterService is null or vendor intf is not enabled"); 86 return false; 87 } 88 89 Log.d(TAG, "interopMatchName: feature=" + feature.name() + ", name=" + name); 90 if (name == null) { 91 return false; 92 } 93 94 boolean matched = adapterService.interopMatchName(feature, name); 95 Log.d(TAG, "interopMatchName: matched=" + matched); 96 return matched; 97 } 98 99 /** 100 * Check if a given address or remote device name matches a known interoperability workaround 101 * identified by the interop feature. remote device name will be fetched internally based on 102 * the given address at stack layer. 103 * 104 * @param feature a given interop feature defined in {@link InteropFeature}. 105 * @param address a given address to be matched. 106 * @return true if matched, false otherwise 107 */ interopMatchAddrOrName(InteropFeature feature, String address)108 public static boolean interopMatchAddrOrName(InteropFeature feature, String address) { 109 AdapterService adapterService = AdapterService.getAdapterService(); 110 if (adapterService == null) { 111 Log.d(TAG, "interopMatchAddrOrName: feature=" + feature.name() 112 + ", adapterService is null or vendor intf is not enabled"); 113 return false; 114 } 115 116 Log.d(TAG, "interopMatchAddrOrName: feature=" + feature.name() + ", address=" + address); 117 if (address == null) { 118 return false; 119 } 120 121 boolean matched = adapterService.interopMatchAddrOrName(feature, address); 122 Log.d(TAG, "interopMatchAddrOrName: matched=" + matched); 123 return matched; 124 } 125 126 /** 127 * Add a dynamic address interop database entry identified by the interop feature 128 * for a device matching the first length bytes of addr. 129 * 130 * @param feature a given interop feature defined in {@link InteropFeature}. 131 * @param address a given address to be added. 132 * @param length the number of bytes of address to be stored, 133 * length must be in [1,6], and usually it is 3. 134 */ interopDatabaseAddAddr(InteropFeature feature, String address, int length)135 public static void interopDatabaseAddAddr(InteropFeature feature, 136 String address, int length) { 137 AdapterService adapterService = AdapterService.getAdapterService(); 138 if (adapterService == null) { 139 Log.d(TAG, "interopDatabaseAddAddr: feature=" + feature.name() 140 + ", adapterService is null or vendor intf is not enabled"); 141 return; 142 } 143 144 Log.d(TAG, "interopDatabaseAddAddr: feature=" + feature.name() 145 + ", address=" + address + ", length=" + length); 146 if (address == null || (length <= 0 || length > 6)) { 147 return; 148 } 149 150 adapterService.interopDatabaseAddAddr(feature, address, length); 151 } 152 153 /** 154 * Remove a dynamic address interop database entry identified by the interop feature 155 * for a device matching the addr. 156 * 157 * @param feature a given interop feature defined in {@link InteropFeature}. 158 * @param address a given address to be removed. 159 */ interopDatabaseRemoveAddr(InteropFeature feature, String address)160 public static void interopDatabaseRemoveAddr(InteropFeature feature, String address) { 161 AdapterService adapterService = AdapterService.getAdapterService(); 162 if (adapterService == null) { 163 Log.d(TAG, "interopDatabaseRemoveAddr: feature=" + feature.name() 164 + ", adapterService is null or vendor intf is not enabled"); 165 return; 166 } 167 168 Log.d(TAG, "interopDatabaseRemoveAddr: feature=" + feature.name() + ", address=" + address); 169 if (address == null) { 170 return; 171 } 172 173 adapterService.interopDatabaseRemoveAddr(feature, address); 174 } 175 176 /** 177 * Add a dynamic name interop database entry identified by the interop feature for the name. 178 * 179 * @param feature a given interop feature defined in {@link InteropFeature}. 180 * @param name a given name to be added. 181 */ interopDatabaseAddName(InteropFeature feature, String name)182 public static void interopDatabaseAddName(InteropFeature feature, String name) { 183 AdapterService adapterService = AdapterService.getAdapterService(); 184 if (adapterService == null) { 185 Log.d(TAG, "interopDatabaseAddName: feature=" + feature.name() 186 + ", adapterService is null or vendor intf is not enabled"); 187 return; 188 } 189 190 Log.d(TAG, "interopDatabaseAddName: feature=" + feature.name() + ", name=" + name); 191 if (name == null) { 192 return; 193 } 194 195 adapterService.interopDatabaseAddName(feature, name); 196 } 197 198 /** 199 * Remove a dynamic name interop database entry identified by the interop feature for the name. 200 * 201 * @param feature a given interop feature defined in {@link InteropFeature}. 202 * @param name a given name to be removed. 203 */ interopDatabaseRemoveName(InteropFeature feature, String name)204 public static void interopDatabaseRemoveName(InteropFeature feature, String name) { 205 AdapterService adapterService = AdapterService.getAdapterService(); 206 if (adapterService == null) { 207 Log.d(TAG, "interopDatabaseRemoveName: feature=" + feature.name() 208 + ", adapterService is null or vendor intf is not enabled"); 209 return; 210 } 211 212 Log.d(TAG, "interopDatabaseRemoveName: feature=" + feature.name() + ", name=" + name); 213 if (name == null) { 214 return; 215 } 216 217 adapterService.interopDatabaseRemoveName(feature, name); 218 } 219 } 220