• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.NonNull;
20 import android.annotation.Nullable;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Objects;
27 
28 /**
29  * Represents the codec status (configuration and capability) for a Bluetooth
30  * A2DP source device.
31  *
32  * {@see BluetoothA2dp}
33  */
34 public final class BluetoothCodecStatus implements Parcelable {
35     /**
36      * Extra for the codec configuration intents of the individual profiles.
37      *
38      * This extra represents the current codec status of the A2DP
39      * profile.
40      */
41     public static final String EXTRA_CODEC_STATUS =
42             "android.bluetooth.extra.CODEC_STATUS";
43 
44     private final @Nullable BluetoothCodecConfig mCodecConfig;
45     private final @Nullable List<BluetoothCodecConfig> mCodecsLocalCapabilities;
46     private final @Nullable List<BluetoothCodecConfig> mCodecsSelectableCapabilities;
47 
48     /**
49      * Creates a new BluetoothCodecStatus.
50      *
51      * @hide
52      */
BluetoothCodecStatus(@ullable BluetoothCodecConfig codecConfig, @Nullable List<BluetoothCodecConfig> codecsLocalCapabilities, @Nullable List<BluetoothCodecConfig> codecsSelectableCapabilities)53     public BluetoothCodecStatus(@Nullable BluetoothCodecConfig codecConfig,
54             @Nullable List<BluetoothCodecConfig> codecsLocalCapabilities,
55             @Nullable List<BluetoothCodecConfig> codecsSelectableCapabilities) {
56         mCodecConfig = codecConfig;
57         mCodecsLocalCapabilities = codecsLocalCapabilities;
58         mCodecsSelectableCapabilities = codecsSelectableCapabilities;
59     }
60 
BluetoothCodecStatus(Parcel in)61     private BluetoothCodecStatus(Parcel in) {
62         mCodecConfig = in.readTypedObject(BluetoothCodecConfig.CREATOR);
63         mCodecsLocalCapabilities = in.createTypedArrayList(BluetoothCodecConfig.CREATOR);
64         mCodecsSelectableCapabilities = in.createTypedArrayList(BluetoothCodecConfig.CREATOR);
65     }
66 
67     @Override
equals(@ullable Object o)68     public boolean equals(@Nullable Object o) {
69         if (o instanceof BluetoothCodecStatus) {
70             BluetoothCodecStatus other = (BluetoothCodecStatus) o;
71             return (Objects.equals(other.mCodecConfig, mCodecConfig)
72                     && sameCapabilities(other.mCodecsLocalCapabilities, mCodecsLocalCapabilities)
73                     && sameCapabilities(other.mCodecsSelectableCapabilities,
74                     mCodecsSelectableCapabilities));
75         }
76         return false;
77     }
78 
79     /**
80      * Checks whether two lists of capabilities contain same capabilities.
81      * The order of the capabilities in each list is ignored.
82      *
83      * @param c1 the first list of capabilities to compare
84      * @param c2 the second list of capabilities to compare
85      * @return {@code true} if both lists contain same capabilities
86      */
sameCapabilities(@ullable List<BluetoothCodecConfig> c1, @Nullable List<BluetoothCodecConfig> c2)87     private static boolean sameCapabilities(@Nullable List<BluetoothCodecConfig> c1,
88                                            @Nullable List<BluetoothCodecConfig> c2) {
89         if (c1 == null) {
90             return (c2 == null);
91         }
92         if (c2 == null) {
93             return false;
94         }
95         if (c1.size() != c2.size()) {
96             return false;
97         }
98         return c1.containsAll(c2);
99     }
100 
101     /**
102      * Checks whether the codec config matches the selectable capabilities.
103      * Any parameters of the codec config with NONE value will be considered a wildcard matching.
104      *
105      * @param codecConfig the codec config to compare against
106      * @return {@code true} if the codec config matches, {@code false} otherwise
107      */
isCodecConfigSelectable(@ullable BluetoothCodecConfig codecConfig)108     public boolean isCodecConfigSelectable(@Nullable BluetoothCodecConfig codecConfig) {
109         if (codecConfig == null || !codecConfig.hasSingleSampleRate()
110                 || !codecConfig.hasSingleBitsPerSample() || !codecConfig.hasSingleChannelMode()) {
111             return false;
112         }
113         for (BluetoothCodecConfig selectableConfig : mCodecsSelectableCapabilities) {
114             if (codecConfig.getCodecType() != selectableConfig.getCodecType()) {
115                 continue;
116             }
117             int sampleRate = codecConfig.getSampleRate();
118             if ((sampleRate & selectableConfig.getSampleRate()) == 0
119                     && sampleRate != BluetoothCodecConfig.SAMPLE_RATE_NONE) {
120                 continue;
121             }
122             int bitsPerSample = codecConfig.getBitsPerSample();
123             if ((bitsPerSample & selectableConfig.getBitsPerSample()) == 0
124                     && bitsPerSample != BluetoothCodecConfig.BITS_PER_SAMPLE_NONE) {
125                 continue;
126             }
127             int channelMode = codecConfig.getChannelMode();
128             if ((channelMode & selectableConfig.getChannelMode()) == 0
129                     && channelMode != BluetoothCodecConfig.CHANNEL_MODE_NONE) {
130                 continue;
131             }
132             return true;
133         }
134         return false;
135     }
136 
137     /**
138      * Returns a hash based on the codec config and local capabilities.
139      */
140     @Override
hashCode()141     public int hashCode() {
142         return Objects.hash(mCodecConfig, mCodecsLocalCapabilities,
143                 mCodecsLocalCapabilities);
144     }
145 
146     /**
147      * Returns a {@link String} that describes each BluetoothCodecStatus parameter
148      * current value.
149      */
150     @Override
toString()151     public String toString() {
152         return "{mCodecConfig:" + mCodecConfig
153                 + ",mCodecsLocalCapabilities:" + mCodecsLocalCapabilities
154                 + ",mCodecsSelectableCapabilities:" + mCodecsSelectableCapabilities
155                 + "}";
156     }
157 
158     /**
159      * @return 0
160      * @hide
161      */
162     @Override
describeContents()163     public int describeContents() {
164         return 0;
165     }
166 
167     public static final @android.annotation.NonNull Parcelable.Creator<BluetoothCodecStatus> CREATOR =
168             new Parcelable.Creator<BluetoothCodecStatus>() {
169                 public BluetoothCodecStatus createFromParcel(Parcel in) {
170                     return new BluetoothCodecStatus(in);
171                 }
172 
173                 public BluetoothCodecStatus[] newArray(int size) {
174                     return new BluetoothCodecStatus[size];
175                 }
176             };
177 
178     /**
179      * Flattens the object to a parcel.
180      *
181      * @param out The Parcel in which the object should be written
182      * @param flags Additional flags about how the object should be written
183      */
184     @Override
writeToParcel(@onNull Parcel out, int flags)185     public void writeToParcel(@NonNull Parcel out, int flags) {
186         out.writeTypedObject(mCodecConfig, 0);
187         out.writeTypedList(mCodecsLocalCapabilities);
188         out.writeTypedList(mCodecsSelectableCapabilities);
189     }
190 
191     /**
192      * Returns the current codec configuration.
193      */
getCodecConfig()194     public @Nullable BluetoothCodecConfig getCodecConfig() {
195         return mCodecConfig;
196     }
197 
198     /**
199      * Returns the codecs local capabilities.
200      */
getCodecsLocalCapabilities()201     public @NonNull List<BluetoothCodecConfig> getCodecsLocalCapabilities() {
202         return (mCodecsLocalCapabilities == null)
203                 ? Collections.emptyList() : mCodecsLocalCapabilities;
204     }
205 
206     /**
207      * Returns the codecs selectable capabilities.
208      */
getCodecsSelectableCapabilities()209     public @NonNull List<BluetoothCodecConfig> getCodecsSelectableCapabilities() {
210         return (mCodecsSelectableCapabilities == null)
211                 ? Collections.emptyList() : mCodecsSelectableCapabilities;
212     }
213 
214     /**
215      * Builder for {@link BluetoothCodecStatus}.
216      */
217     public static final class Builder {
218         private BluetoothCodecConfig mCodecConfig = null;
219         private List<BluetoothCodecConfig> mCodecsLocalCapabilities = null;
220         private List<BluetoothCodecConfig> mCodecsSelectableCapabilities = null;
221 
222         /**
223          * Set Bluetooth codec config for this codec status.
224          *
225          * @param codecConfig of this codec status
226          * @return the same Builder instance
227          */
setCodecConfig(@onNull BluetoothCodecConfig codecConfig)228         public @NonNull Builder setCodecConfig(@NonNull BluetoothCodecConfig codecConfig) {
229             mCodecConfig = codecConfig;
230             return this;
231         }
232 
233         /**
234          * Set codec local capabilities list for this codec status.
235          *
236          * @param codecsLocalCapabilities of this codec status
237          * @return the same Builder instance
238          */
setCodecsLocalCapabilities( @onNull List<BluetoothCodecConfig> codecsLocalCapabilities)239         public @NonNull Builder setCodecsLocalCapabilities(
240                 @NonNull List<BluetoothCodecConfig> codecsLocalCapabilities) {
241             mCodecsLocalCapabilities = codecsLocalCapabilities;
242             return this;
243         }
244 
245         /**
246          * Set codec selectable capabilities list for this codec status.
247          *
248          * @param codecsSelectableCapabilities of this codec status
249          * @return the same Builder instance
250          */
setCodecsSelectableCapabilities( @onNull List<BluetoothCodecConfig> codecsSelectableCapabilities)251         public @NonNull Builder setCodecsSelectableCapabilities(
252                 @NonNull List<BluetoothCodecConfig> codecsSelectableCapabilities) {
253             mCodecsSelectableCapabilities = codecsSelectableCapabilities;
254             return this;
255         }
256 
257         /**
258          * Build {@link BluetoothCodecStatus}.
259          * @return new BluetoothCodecStatus built
260          */
build()261         public @NonNull BluetoothCodecStatus build() {
262             return new BluetoothCodecStatus(mCodecConfig, mCodecsLocalCapabilities,
263                     mCodecsSelectableCapabilities);
264         }
265     }
266 }
267