1 /* 2 * Copyright 2022 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 android.bluetooth; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Objects; 29 30 /** 31 * Represents Bluetooth Audio Policies of a Handsfree (HF) device (if HFP is used) 32 * and Call Terminal (CT) device (if BLE Audio is used), which describes the 33 * preferences of allowing or disallowing audio based on the use cases. The HF/CT 34 * devices shall send objects of this class to send its preference to the AG/CG 35 * devices. 36 * 37 * <p>HF/CT side applications on can use {@link BluetoothDevice#requestAudioPolicyAsSink} 38 * API to set and send a {@link BluetoothSinkAudioPolicy} object containing the 39 * preference/policy values. This object will be stored in the memory of HF/CT 40 * side, will be send to the AG/CG side using Android Specific AT Commands and will 41 * be stored in the AG side memory and database. 42 * 43 * <p>HF/CT side API {@link BluetoothDevice#getRequestedAudioPolicyAsSink} can be used to retrieve 44 * the stored audio policies currently. 45 * 46 * <p>Note that the setter APIs of this class will only set the values of the 47 * object. To actually set the policies, API {@link BluetoothDevice#requestAudioPolicyAsSink} 48 * must need to be invoked with the {@link BluetoothSinkAudioPolicy} object. 49 * 50 * <p>Note that any API related to this feature should be used after configuring 51 * the support of the AG device and after checking whether the AG device supports 52 * this feature or not by invoking {@link BluetoothDevice#isRequestAudioPolicyAsSinkSupported}. 53 * Only after getting a {@link BluetoothStatusCodes#FEATURE_SUPPORTED} response 54 * from the API should the APIs related to this feature be used. 55 * 56 * 57 * @hide 58 */ 59 @SystemApi 60 public final class BluetoothSinkAudioPolicy implements Parcelable { 61 62 /** 63 * @hide 64 */ 65 @Retention(RetentionPolicy.SOURCE) 66 @IntDef( 67 prefix = {"POLICY_"}, 68 value = { 69 POLICY_UNCONFIGURED, 70 POLICY_ALLOWED, 71 POLICY_NOT_ALLOWED, 72 } 73 ) 74 public @interface AudioPolicyValues{} 75 76 /** 77 * Audio behavior not configured for the policy. 78 * 79 * If a policy is set with this value, it means that the policy is not 80 * configured with a value yet and should not be used to make any decision. 81 * @hide 82 */ 83 @SystemApi 84 public static final int POLICY_UNCONFIGURED = 0; 85 86 /** 87 * Audio is preferred by HF device for the policy. 88 * 89 * If a policy is set with this value, then the HF device will prefer the 90 * audio for the policy use case. For example, if the Call Establish audio 91 * policy is set with this value, then the HF will prefer the audio 92 * during making or picking up a call. 93 * @hide 94 */ 95 @SystemApi 96 public static final int POLICY_ALLOWED = 1; 97 98 /** 99 * Audio is not preferred by HF device for the policy. 100 * 101 * If a policy is set with this value, then the HF device will not prefer the 102 * audio for the policy use case. For example, if the Call Establish audio 103 * policy is set with this value, then the HF will not prefer the audio 104 * during making or picking up a call. 105 * @hide 106 */ 107 @SystemApi 108 public static final int POLICY_NOT_ALLOWED = 2; 109 110 /** 111 * The feature ID used in the HFP AT command. 112 * @hide 113 */ 114 public static final String HFP_SET_SINK_AUDIO_POLICY_ID = "SINKAUDIOPOLICY"; 115 116 @AudioPolicyValues private final int mCallEstablishPolicy; 117 @AudioPolicyValues private final int mConnectingTimePolicy; 118 @AudioPolicyValues private final int mInBandRingtonePolicy; 119 120 /** 121 * @hide 122 */ BluetoothSinkAudioPolicy(int callEstablishPolicy, int connectingTimePolicy, int inBandRingtonePolicy)123 public BluetoothSinkAudioPolicy(int callEstablishPolicy, 124 int connectingTimePolicy, int inBandRingtonePolicy) { 125 mCallEstablishPolicy = callEstablishPolicy; 126 mConnectingTimePolicy = connectingTimePolicy; 127 mInBandRingtonePolicy = inBandRingtonePolicy; 128 } 129 130 /** 131 * Get Call establishment policy audio policy. 132 * <p>This policy is used to determine the audio preference when the 133 * HF device makes or answers a call. That is, if this device 134 * makes or answers a call, is the audio preferred by HF. 135 * 136 * @return the call pick up audio policy value 137 * 138 * @hide 139 */ 140 @SystemApi getCallEstablishPolicy()141 public @AudioPolicyValues int getCallEstablishPolicy() { 142 return mCallEstablishPolicy; 143 } 144 145 /** 146 * Get during connection audio up policy. 147 * <p>This policy is used to determine the audio preference when the 148 * HF device connects with the AG device. That is, when the 149 * HF device gets connected, should the HF become active and get audio 150 * is decided by this policy. This also covers the case of during a call. 151 * If the HF connects with the AG during an ongoing call, should the call 152 * audio be routed to the HF will be decided by this policy. 153 * 154 * @return the during connection audio policy value 155 * 156 * @hide 157 */ 158 @SystemApi getActiveDevicePolicyAfterConnection()159 public @AudioPolicyValues int getActiveDevicePolicyAfterConnection() { 160 return mConnectingTimePolicy; 161 } 162 163 /** 164 * Get In band ringtone audio up policy. 165 * <p>This policy is used to determine the audio preference of the 166 * in band ringtone. That is, if there is an incoming call, should the 167 * inband ringtone audio be routed to the HF will be decided by this policy. 168 * 169 * @return the in band ringtone audio policy value 170 * 171 * @hide 172 */ 173 @SystemApi getInBandRingtonePolicy()174 public @AudioPolicyValues int getInBandRingtonePolicy() { 175 return mInBandRingtonePolicy; 176 } 177 178 @Override toString()179 public String toString() { 180 StringBuilder builder = new StringBuilder("BluetoothSinkAudioPolicy{"); 181 builder.append("mCallEstablishPolicy: "); 182 builder.append(mCallEstablishPolicy); 183 builder.append(", mConnectingTimePolicy: "); 184 builder.append(mConnectingTimePolicy); 185 builder.append(", mInBandRingtonePolicy: "); 186 builder.append(mInBandRingtonePolicy); 187 builder.append("}"); 188 return builder.toString(); 189 } 190 191 /** 192 * {@link Parcelable.Creator} interface implementation. 193 */ 194 public static final @android.annotation.NonNull Parcelable.Creator<BluetoothSinkAudioPolicy> 195 CREATOR = new Parcelable.Creator<BluetoothSinkAudioPolicy>() { 196 @Override 197 public BluetoothSinkAudioPolicy createFromParcel(@NonNull Parcel in) { 198 return new BluetoothSinkAudioPolicy( 199 in.readInt(), in.readInt(), in.readInt()); 200 } 201 202 @Override 203 public BluetoothSinkAudioPolicy[] newArray(int size) { 204 return new BluetoothSinkAudioPolicy[size]; 205 } 206 }; 207 208 @Override writeToParcel(@onNull Parcel out, int flags)209 public void writeToParcel(@NonNull Parcel out, int flags) { 210 out.writeInt(mCallEstablishPolicy); 211 out.writeInt(mConnectingTimePolicy); 212 out.writeInt(mInBandRingtonePolicy); 213 } 214 215 /** 216 * @hide 217 */ 218 @Override describeContents()219 public int describeContents() { 220 return 0; 221 } 222 223 @Override equals(@ullable Object o)224 public boolean equals(@Nullable Object o) { 225 if (o instanceof BluetoothSinkAudioPolicy) { 226 BluetoothSinkAudioPolicy other = (BluetoothSinkAudioPolicy) o; 227 return (other.mCallEstablishPolicy == mCallEstablishPolicy 228 && other.mConnectingTimePolicy == mConnectingTimePolicy 229 && other.mInBandRingtonePolicy == mInBandRingtonePolicy); 230 } 231 return false; 232 } 233 234 /** 235 * Returns a hash representation of this BluetoothCodecConfig 236 * based on all the config values. 237 * 238 * @hide 239 */ 240 @Override hashCode()241 public int hashCode() { 242 return Objects.hash(mCallEstablishPolicy, mConnectingTimePolicy, mInBandRingtonePolicy); 243 } 244 245 /** 246 * Builder for {@link BluetoothSinkAudioPolicy}. 247 * <p> By default, the audio policy values will be set to 248 * {@link BluetoothSinkAudioPolicy#POLICY_UNCONFIGURED}. 249 */ 250 public static final class Builder { 251 private int mCallEstablishPolicy = POLICY_UNCONFIGURED; 252 private int mConnectingTimePolicy = POLICY_UNCONFIGURED; 253 private int mInBandRingtonePolicy = POLICY_UNCONFIGURED; 254 Builder()255 public Builder() { 256 257 } 258 Builder(@onNull BluetoothSinkAudioPolicy policies)259 public Builder(@NonNull BluetoothSinkAudioPolicy policies) { 260 mCallEstablishPolicy = policies.mCallEstablishPolicy; 261 mConnectingTimePolicy = policies.mConnectingTimePolicy; 262 mInBandRingtonePolicy = policies.mInBandRingtonePolicy; 263 } 264 265 /** 266 * Set Call Establish (pick up and answer) policy. 267 * <p>This policy is used to determine the audio preference when the 268 * HF device makes or answers a call. That is, if this device 269 * makes or answers a call, is the audio preferred by HF. 270 * <p>If set to {@link BluetoothSinkAudioPolicy#POLICY_ALLOWED}, answering or making 271 * a call from the HF device will route the call audio to it. 272 * If set to {@link BluetoothSinkAudioPolicy#POLICY_NOT_ALLOWED}, answering or making 273 * a call from the HF device will NOT route the call audio to it. 274 * 275 * @return reference to the current object 276 * 277 * @hide 278 */ setCallEstablishPolicy( @udioPolicyValues int callEstablishPolicy)279 @SystemApi public @NonNull Builder setCallEstablishPolicy( 280 @AudioPolicyValues int callEstablishPolicy) { 281 mCallEstablishPolicy = callEstablishPolicy; 282 return this; 283 } 284 285 /** 286 * Set during connection audio up policy. 287 * <p>This policy is used to determine the audio preference when the 288 * HF device connects with the AG device. That is, when the 289 * HF device gets connected, should the HF become active and get audio 290 * is decided by this policy. This also covers the case of during a call. 291 * If the HF connects with the AG during an ongoing call, should the call 292 * audio be routed to the HF will be decided by this policy. 293 * <p>If set to {@link BluetoothSinkAudioPolicy#POLICY_ALLOWED}, connecting HF 294 * during a call will route the call audio to it. 295 * If set to {@link BluetoothSinkAudioPolicy#POLICY_NOT_ALLOWED}, connecting HF 296 * during a call will NOT route the call audio to it. 297 * 298 * @return reference to the current object 299 * 300 * @hide 301 */ setActiveDevicePolicyAfterConnection( @udioPolicyValues int connectingTimePolicy)302 @SystemApi public @NonNull Builder setActiveDevicePolicyAfterConnection( 303 @AudioPolicyValues int connectingTimePolicy) { 304 mConnectingTimePolicy = connectingTimePolicy; 305 return this; 306 } 307 308 /** 309 * Set In band ringtone audio up policy. 310 * <p>This policy is used to determine the audio preference of the 311 * in band ringtone. That is, if there is an incoming call, should the 312 * inband ringtone audio be routed to the HF will be decided by this policy. 313 * <p>If set to {@link BluetoothSinkAudioPolicy#POLICY_ALLOWED}, there will be 314 * in band ringtone in the HF device during an incoming call. 315 * If set to {@link BluetoothSinkAudioPolicy#POLICY_NOT_ALLOWED}, there will NOT 316 * be in band ringtone in the HF device during an incoming call. 317 * 318 * @return reference to the current object 319 * 320 * @hide 321 */ setInBandRingtonePolicy( @udioPolicyValues int inBandRingtonePolicy)322 @SystemApi public @NonNull Builder setInBandRingtonePolicy( 323 @AudioPolicyValues int inBandRingtonePolicy) { 324 mInBandRingtonePolicy = inBandRingtonePolicy; 325 return this; 326 } 327 328 /** 329 * Build {@link BluetoothSinkAudioPolicy}. 330 * @return new BluetoothSinkAudioPolicy object 331 * 332 * @hide 333 */ build()334 @SystemApi public @NonNull BluetoothSinkAudioPolicy build() { 335 return new BluetoothSinkAudioPolicy( 336 mCallEstablishPolicy, mConnectingTimePolicy, mInBandRingtonePolicy); 337 } 338 } 339 } 340