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. These APIs will call stack layer's interop APIs of 24 * interop.cc to do matching or entry adding/removing. 25 */ 26 public class InteropUtil { 27 private static final String TAG = "InteropUtil"; 28 29 /** 30 * Add interop feature from device/include/interop.h to below InteropFeature if this feature 31 * needs to be matched at java layer. Feature's name will be passed to stack layer to do 32 * matching, so make sure that the added feature's name is exactly same as that in 33 * device/include/interop.h. 34 */ 35 public enum InteropFeature { 36 INTEROP_NOT_UPDATE_AVRCP_PAUSED_TO_REMOTE, 37 INTEROP_PHONE_POLICY_INCREASED_DELAY_CONNECT_OTHER_PROFILES, 38 INTEROP_PHONE_POLICY_REDUCED_DELAY_CONNECT_OTHER_PROFILES, 39 INTEROP_HFP_FAKE_INCOMING_CALL_INDICATOR, 40 INTEROP_HFP_SEND_CALL_INDICATORS_BACK_TO_BACK, 41 INTEROP_SETUP_SCO_WITH_NO_DELAY_AFTER_SLC_DURING_CALL, 42 INTEROP_RETRY_SCO_AFTER_REMOTE_REJECT_SCO, 43 INTEROP_ADV_PBAP_VER_1_2; 44 } 45 46 /** 47 * Check if a given address matches a known interoperability workaround identified by the 48 * interop feature. 49 * 50 * @param feature a given interop feature defined in {@link InteropFeature}. 51 * @param address a given address to be matched. 52 * @return true if matched, false otherwise. 53 */ interopMatchAddr(InteropFeature feature, String address)54 public static boolean interopMatchAddr(InteropFeature feature, String address) { 55 AdapterService adapterService = AdapterService.getAdapterService(); 56 if (adapterService == null) { 57 Log.d( 58 TAG, 59 "interopMatchAddr: feature=" 60 + feature.name() 61 + ", adapterService is null or vendor intf is not enabled"); 62 return false; 63 } 64 65 Log.d(TAG, "interopMatchAddr: feature=" + feature.name() + ", address=" + address); 66 if (address == null) { 67 return false; 68 } 69 70 boolean matched = adapterService.interopMatchAddr(feature, address); 71 Log.d(TAG, "interopMatchAddr: matched=" + matched); 72 return matched; 73 } 74 75 /** 76 * Check if a given name matches a known interoperability workaround identified by the interop 77 * feature. 78 * 79 * @param feature a given interop feature defined in {@link InteropFeature}. 80 * @param name a given name to be matched. 81 * @return true if matched, false otherwise. 82 */ interopMatchName(InteropFeature feature, String name)83 public static boolean interopMatchName(InteropFeature feature, String name) { 84 AdapterService adapterService = AdapterService.getAdapterService(); 85 if (adapterService == null) { 86 Log.d( 87 TAG, 88 "interopMatchName: feature=" 89 + feature.name() 90 + ", adapterService is null or vendor intf is not enabled"); 91 return false; 92 } 93 94 Log.d(TAG, "interopMatchName: feature=" + feature.name() + ", name=" + name); 95 if (name == null) { 96 return false; 97 } 98 99 boolean matched = adapterService.interopMatchName(feature, name); 100 Log.d(TAG, "interopMatchName: matched=" + matched); 101 return matched; 102 } 103 104 /** 105 * Check if a given address or remote device name matches a known interoperability workaround 106 * identified by the interop feature. remote device name will be fetched internally based on the 107 * given address at stack layer. 108 * 109 * @param feature a given interop feature defined in {@link InteropFeature}. 110 * @param address a given address to be matched. 111 * @return true if matched, false otherwise 112 */ interopMatchAddrOrName(InteropFeature feature, String address)113 public static boolean interopMatchAddrOrName(InteropFeature feature, String address) { 114 AdapterService adapterService = AdapterService.getAdapterService(); 115 if (adapterService == null) { 116 Log.d( 117 TAG, 118 "interopMatchAddrOrName: feature=" 119 + feature.name() 120 + ", adapterService is null or vendor intf is not enabled"); 121 return false; 122 } 123 124 Log.d(TAG, "interopMatchAddrOrName: feature=" + feature.name() + ", address=" + address); 125 if (address == null) { 126 return false; 127 } 128 129 boolean matched = adapterService.interopMatchAddrOrName(feature, address); 130 Log.d(TAG, "interopMatchAddrOrName: matched=" + matched); 131 return matched; 132 } 133 134 /** 135 * Add a dynamic address interop database entry identified by the interop feature for a device 136 * matching the first length bytes of addr. 137 * 138 * @param feature a given interop feature defined in {@link InteropFeature}. 139 * @param address a given address to be added. 140 * @param length the number of bytes of address to be stored, length must be in [1,6], and 141 * usually it is 3. 142 */ interopDatabaseAddAddr(InteropFeature feature, String address, int length)143 public static void interopDatabaseAddAddr(InteropFeature feature, String address, int length) { 144 AdapterService adapterService = AdapterService.getAdapterService(); 145 if (adapterService == null) { 146 Log.d( 147 TAG, 148 "interopDatabaseAddAddr: feature=" 149 + feature.name() 150 + ", adapterService is null or vendor intf is not enabled"); 151 return; 152 } 153 154 Log.d( 155 TAG, 156 "interopDatabaseAddAddr: feature=" 157 + feature.name() 158 + ", address=" 159 + address 160 + ", length=" 161 + length); 162 if (address == null || (length <= 0 || length > 6)) { 163 return; 164 } 165 166 adapterService.interopDatabaseAddAddr(feature, address, length); 167 } 168 169 /** 170 * Remove a dynamic address interop database entry identified by the interop feature for a 171 * device matching the addr. 172 * 173 * @param feature a given interop feature defined in {@link InteropFeature}. 174 * @param address a given address to be removed. 175 */ interopDatabaseRemoveAddr(InteropFeature feature, String address)176 public static void interopDatabaseRemoveAddr(InteropFeature feature, String address) { 177 AdapterService adapterService = AdapterService.getAdapterService(); 178 if (adapterService == null) { 179 Log.d( 180 TAG, 181 "interopDatabaseRemoveAddr: feature=" 182 + feature.name() 183 + ", adapterService is null or vendor intf is not enabled"); 184 return; 185 } 186 187 Log.d(TAG, "interopDatabaseRemoveAddr: feature=" + feature.name() + ", address=" + address); 188 if (address == null) { 189 return; 190 } 191 192 adapterService.interopDatabaseRemoveAddr(feature, address); 193 } 194 195 /** 196 * Add a dynamic name interop database entry identified by the interop feature for the name. 197 * 198 * @param feature a given interop feature defined in {@link InteropFeature}. 199 * @param name a given name to be added. 200 */ interopDatabaseAddName(InteropFeature feature, String name)201 public static void interopDatabaseAddName(InteropFeature feature, String name) { 202 AdapterService adapterService = AdapterService.getAdapterService(); 203 if (adapterService == null) { 204 Log.d( 205 TAG, 206 "interopDatabaseAddName: feature=" 207 + feature.name() 208 + ", adapterService is null or vendor intf is not enabled"); 209 return; 210 } 211 212 Log.d(TAG, "interopDatabaseAddName: feature=" + feature.name() + ", name=" + name); 213 if (name == null) { 214 return; 215 } 216 217 adapterService.interopDatabaseAddName(feature, name); 218 } 219 220 /** 221 * Remove a dynamic name interop database entry identified by the interop feature for the name. 222 * 223 * @param feature a given interop feature defined in {@link InteropFeature}. 224 * @param name a given name to be removed. 225 */ interopDatabaseRemoveName(InteropFeature feature, String name)226 public static void interopDatabaseRemoveName(InteropFeature feature, String name) { 227 AdapterService adapterService = AdapterService.getAdapterService(); 228 if (adapterService == null) { 229 Log.d( 230 TAG, 231 "interopDatabaseRemoveName: feature=" 232 + feature.name() 233 + ", adapterService is null or vendor intf is not enabled"); 234 return; 235 } 236 237 Log.d(TAG, "interopDatabaseRemoveName: feature=" + feature.name() + ", name=" + name); 238 if (name == null) { 239 return; 240 } 241 242 adapterService.interopDatabaseRemoveName(feature, name); 243 } 244 } 245