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