1 /*
2  * Copyright 2021 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 package android.media;
17 
18 import static android.media.audio.Flags.FLAG_SCO_MANAGED_BY_AUDIO;
19 
20 import android.annotation.FlaggedApi;
21 import android.annotation.NonNull;
22 import android.annotation.SystemApi;
23 import android.bluetooth.BluetoothProfile;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 
27 /**
28  * Contains information about Bluetooth profile connection state changed
29  * {@hide}
30  */
31 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
32 public final class BluetoothProfileConnectionInfo implements Parcelable {
33     private final int mProfile;
34     private final boolean mSupprNoisy;
35     private final int mVolume;
36     private final boolean mIsLeOutput;
37 
BluetoothProfileConnectionInfo(int profile, boolean suppressNoisyIntent, int volume, boolean isLeOutput)38     private BluetoothProfileConnectionInfo(int profile, boolean suppressNoisyIntent,
39             int volume, boolean isLeOutput) {
40         mProfile = profile;
41         mSupprNoisy = suppressNoisyIntent;
42         mVolume = volume;
43         mIsLeOutput = isLeOutput;
44     }
45 
46     /**
47      * Constructor used by BtHelper when a profile is connected
48      * {@hide}
49      */
BluetoothProfileConnectionInfo(int profile)50     public BluetoothProfileConnectionInfo(int profile) {
51         this(profile, false, -1, false);
52     }
53 
54     public static final @NonNull Parcelable.Creator<BluetoothProfileConnectionInfo> CREATOR =
55             new Parcelable.Creator<BluetoothProfileConnectionInfo>() {
56                 @Override
57                 public BluetoothProfileConnectionInfo createFromParcel(Parcel source) {
58                     return new BluetoothProfileConnectionInfo(source.readInt(),
59                             source.readBoolean(), source.readInt(), source.readBoolean());
60                 }
61 
62                 @Override
63                 public BluetoothProfileConnectionInfo[] newArray(int size) {
64                     return new BluetoothProfileConnectionInfo[size];
65                 }
66             };
67 
68     @Override
writeToParcel(@onNull Parcel dest, @WriteFlags int flags)69     public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
70         dest.writeInt(mProfile);
71         dest.writeBoolean(mSupprNoisy);
72         dest.writeInt(mVolume);
73         dest.writeBoolean(mIsLeOutput);
74     }
75 
76     @Override
describeContents()77     public int describeContents() {
78         return 0;
79     }
80 
81     /**
82      * Constructor for A2dp info
83      *
84      * @param suppressNoisyIntent if true the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY}
85      * intent will not be sent.
86      *
87      * @param volume of device -1 to ignore value
88      */
createA2dpInfo( boolean suppressNoisyIntent, int volume)89     public static @NonNull BluetoothProfileConnectionInfo createA2dpInfo(
90             boolean suppressNoisyIntent, int volume) {
91         return new BluetoothProfileConnectionInfo(BluetoothProfile.A2DP, suppressNoisyIntent,
92             volume, false);
93     }
94 
95     /**
96      * Constructor for A2dp sink info
97      * The {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be sent.
98      *
99      * @param volume of device -1 to ignore value
100      */
createA2dpSinkInfo(int volume)101     public static @NonNull BluetoothProfileConnectionInfo createA2dpSinkInfo(int volume) {
102         return new BluetoothProfileConnectionInfo(BluetoothProfile.A2DP_SINK, true, volume, false);
103     }
104 
105     /**
106      * Constructor for hearing aid info
107      *
108      * @param suppressNoisyIntent if true the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY}
109      * intent will not be sent.
110      */
createHearingAidInfo( boolean suppressNoisyIntent)111     public static @NonNull BluetoothProfileConnectionInfo createHearingAidInfo(
112             boolean suppressNoisyIntent) {
113         return new BluetoothProfileConnectionInfo(BluetoothProfile.HEARING_AID, suppressNoisyIntent,
114             -1, false);
115     }
116 
117     /**
118      * Factory method for <code>BluetoothProfileConnectionInfo</code> for an LE device
119      * Use this method for an input device connection,
120      * or for an output device connection if the connection volume is unknown,
121      * otherwise use {@link #createLeAudioOutputInfo(boolean, int)}.
122      * @param suppressNoisyIntent if true the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY}
123      * intent will not be sent.
124      *
125      * @param isLeOutput if true mean the device is an output device, if false it's an input device
126      */
createLeAudioInfo( boolean suppressNoisyIntent, boolean isLeOutput)127     public static @NonNull BluetoothProfileConnectionInfo createLeAudioInfo(
128             boolean suppressNoisyIntent, boolean isLeOutput) {
129         return new BluetoothProfileConnectionInfo(BluetoothProfile.LE_AUDIO, suppressNoisyIntent,
130             -1, isLeOutput);
131     }
132 
133     /**
134      * Factory method for <code>BluetoothProfileConnectionInfo</code> for an LE output device
135      * Use this method for an output device connection with a volume to be used at connection
136      * time.
137      * @param suppressNoisyIntent if true the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY}
138      *     intent will not be sent.
139      * @param volume the volume index of the device, -1 if unknown or to be ignored
140      * @return an instance of BluetoothProfileConnectionInfo for the BLE output device that reflects
141      *     the given parameters
142      */
createLeAudioOutputInfo( boolean suppressNoisyIntent, int volume)143     public static @NonNull BluetoothProfileConnectionInfo createLeAudioOutputInfo(
144             boolean suppressNoisyIntent, int volume) {
145         return new BluetoothProfileConnectionInfo(BluetoothProfile.LE_AUDIO, suppressNoisyIntent,
146                 volume, /*isLeOutput*/ true);
147     }
148 
149     /**
150      * @return The profile connection
151      */
getProfile()152     public int getProfile() {
153         return mProfile;
154     }
155 
156     /**
157      * @return {@code true} if {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be
158      * sent
159      */
isSuppressNoisyIntent()160     public boolean isSuppressNoisyIntent() {
161         return mSupprNoisy;
162     }
163 
164     /**
165      * Only for {@link BluetoothProfile.A2DP} profile
166      * @return the volume of the connection or -1 if the value is ignored
167      */
getVolume()168     public int getVolume() {
169         return mVolume;
170     }
171 
172     /**
173      * Only for {@link BluetoothProfile.LE_AUDIO} profile
174      * @return {@code true} is the LE device is an output device, {@code false} if it's an input
175      * device
176      */
isLeOutput()177     public boolean isLeOutput() {
178         return mIsLeOutput;
179     }
180 
181     /**
182      * Factory method for <code>BluetoothProfileConnectionInfo</code> for an HFP device.
183      */
184     @FlaggedApi(FLAG_SCO_MANAGED_BY_AUDIO)
createHfpInfo()185     public static @NonNull BluetoothProfileConnectionInfo createHfpInfo() {
186         return new BluetoothProfileConnectionInfo(BluetoothProfile.HEADSET, false,
187                 -1, false);
188     }
189 }
190