• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 com.android.settingslib.bluetooth;
18 
19 import android.annotation.IntDef;
20 import android.bluetooth.BluetoothHearingAid;
21 import android.bluetooth.BluetoothLeAudio;
22 import android.util.SparseIntArray;
23 
24 import java.lang.annotation.Retention;
25 import java.lang.annotation.RetentionPolicy;
26 import java.util.Objects;
27 
28 /** Hearing aids information and constants that shared within hearing aids related profiles */
29 public class HearingAidInfo {
30 
31     @Retention(RetentionPolicy.SOURCE)
32     @IntDef({
33             DeviceSide.SIDE_INVALID,
34             DeviceSide.SIDE_LEFT,
35             DeviceSide.SIDE_RIGHT,
36             DeviceSide.SIDE_LEFT_AND_RIGHT,
37             DeviceSide.SIDE_MONO
38     })
39 
40     /** Side definition for hearing aids. */
41     public @interface DeviceSide {
42         int SIDE_INVALID = -1;
43         int SIDE_LEFT = 0;
44         int SIDE_RIGHT = 1;
45         int SIDE_LEFT_AND_RIGHT = 2;
46         int SIDE_MONO = 3;
47     }
48 
49     @Retention(java.lang.annotation.RetentionPolicy.SOURCE)
50     @IntDef({
51             DeviceMode.MODE_INVALID,
52             DeviceMode.MODE_MONAURAL,
53             DeviceMode.MODE_BINAURAL,
54             DeviceMode.MODE_BANDED,
55     })
56 
57     /** Mode definition for hearing aids. */
58     public @interface DeviceMode {
59         int MODE_INVALID = -1;
60         int MODE_MONAURAL = 0;
61         int MODE_BINAURAL = 1;
62         int MODE_BANDED = 2;
63     }
64 
65     private final int mSide;
66     private final int mMode;
67     private final long mHiSyncId;
68 
HearingAidInfo(int side, int mode, long hiSyncId)69     private HearingAidInfo(int side, int mode, long hiSyncId) {
70         mSide = side;
71         mMode = mode;
72         mHiSyncId = hiSyncId;
73     }
74 
75     @DeviceSide
getSide()76     public int getSide() {
77         return mSide;
78     }
79 
80     @DeviceMode
getMode()81     public int getMode() {
82         return mMode;
83     }
84 
getHiSyncId()85     public long getHiSyncId() {
86         return mHiSyncId;
87     }
88 
89     @Override
equals(Object o)90     public boolean equals(Object o) {
91         if (this == o) {
92             return true;
93         }
94         if (!(o instanceof HearingAidInfo)) {
95             return false;
96         }
97         HearingAidInfo that = (HearingAidInfo) o;
98         return mSide == that.mSide && mMode == that.mMode && mHiSyncId == that.mHiSyncId;
99     }
100 
101     @Override
hashCode()102     public int hashCode() {
103         return Objects.hash(mSide, mMode, mHiSyncId);
104     }
105 
106     @Override
toString()107     public String toString() {
108         return "HearingAidInfo{"
109                 + "mSide=" + mSide
110                 + ", mMode=" + mMode
111                 + ", mHiSyncId=" + mHiSyncId
112                 + '}';
113     }
114 
115     @DeviceSide
convertAshaDeviceSideToInternalSide(int ashaDeviceSide)116     private static int convertAshaDeviceSideToInternalSide(int ashaDeviceSide) {
117         return ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING.get(
118                 ashaDeviceSide, DeviceSide.SIDE_INVALID);
119     }
120 
121     @DeviceMode
convertAshaDeviceModeToInternalMode(int ashaDeviceMode)122     private static int convertAshaDeviceModeToInternalMode(int ashaDeviceMode) {
123         return ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING.get(
124                 ashaDeviceMode, DeviceMode.MODE_INVALID);
125     }
126 
127     @DeviceSide
convertLeAudioLocationToInternalSide(int leAudioLocation)128     private static int convertLeAudioLocationToInternalSide(int leAudioLocation) {
129         if (leAudioLocation == BluetoothLeAudio.AUDIO_LOCATION_MONO) {
130             return DeviceSide.SIDE_MONO;
131         }
132         boolean isLeft = (leAudioLocation & LE_AUDIO_LOCATION_LEFT) != 0;
133         boolean isRight = (leAudioLocation & LE_AUDIO_LOCATION_RIGHT) != 0;
134         if (isLeft && isRight) {
135             return DeviceSide.SIDE_LEFT_AND_RIGHT;
136         } else if (isLeft) {
137             return DeviceSide.SIDE_LEFT;
138         } else if (isRight) {
139             return DeviceSide.SIDE_RIGHT;
140         }
141         return DeviceSide.SIDE_INVALID;
142     }
143 
144     @DeviceMode
convertHapDeviceTypeToInternalMode(int hapDeviceType)145     private static int convertHapDeviceTypeToInternalMode(int hapDeviceType) {
146         return HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.get(hapDeviceType, DeviceMode.MODE_INVALID);
147     }
148 
149     /** Builder class for constructing {@link HearingAidInfo} objects. */
150     public static final class Builder {
151         private int mSide = DeviceSide.SIDE_INVALID;
152         private int mMode = DeviceMode.MODE_INVALID;
153         private long mHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID;
154 
155         /**
156          * Configure the hearing device mode.
157          * @param ashaDeviceMode one of the hearing aid device modes defined in HearingAidProfile
158          * {@link HearingAidProfile.DeviceMode}
159          */
setAshaDeviceMode(int ashaDeviceMode)160         public Builder setAshaDeviceMode(int ashaDeviceMode) {
161             mMode = convertAshaDeviceModeToInternalMode(ashaDeviceMode);
162             return this;
163         }
164 
165         /**
166          * Configure the hearing device mode.
167          * @param hapDeviceType one of the hearing aid device types defined in HapClientProfile
168          * {@link HapClientProfile.HearingAidType}
169          */
setHapDeviceType(int hapDeviceType)170         public Builder setHapDeviceType(int hapDeviceType) {
171             mMode = convertHapDeviceTypeToInternalMode(hapDeviceType);
172             return this;
173         }
174 
175         /**
176          * Configure the hearing device side.
177          * @param ashaDeviceSide one of the hearing aid device sides defined in HearingAidProfile
178          * {@link HearingAidProfile.DeviceSide}
179          */
setAshaDeviceSide(int ashaDeviceSide)180         public Builder setAshaDeviceSide(int ashaDeviceSide) {
181             mSide = convertAshaDeviceSideToInternalSide(ashaDeviceSide);
182             return this;
183         }
184 
185         /**
186          * Configure the hearing device side.
187          * @param leAudioLocation one of the audio location defined in BluetoothLeAudio
188          * {@link BluetoothLeAudio.AudioLocation}
189          */
setLeAudioLocation(int leAudioLocation)190         public Builder setLeAudioLocation(int leAudioLocation) {
191             mSide = convertLeAudioLocationToInternalSide(leAudioLocation);
192             return this;
193         }
194 
195         /**
196          * Configure the hearing aid hiSyncId.
197          * @param hiSyncId the ASHA hearing aid id
198          */
setHiSyncId(long hiSyncId)199         public Builder setHiSyncId(long hiSyncId) {
200             mHiSyncId = hiSyncId;
201             return this;
202         }
203 
204         /** Build the configured {@link HearingAidInfo} */
build()205         public HearingAidInfo build() {
206             return new HearingAidInfo(mSide, mMode, mHiSyncId);
207         }
208     }
209 
210     private static final int LE_AUDIO_LOCATION_LEFT =
211             BluetoothLeAudio.AUDIO_LOCATION_FRONT_LEFT
212                     | BluetoothLeAudio.AUDIO_LOCATION_BACK_LEFT
213                     | BluetoothLeAudio.AUDIO_LOCATION_FRONT_LEFT_OF_CENTER
214                     | BluetoothLeAudio.AUDIO_LOCATION_SIDE_LEFT
215                     | BluetoothLeAudio.AUDIO_LOCATION_TOP_FRONT_LEFT
216                     | BluetoothLeAudio.AUDIO_LOCATION_TOP_BACK_LEFT
217                     | BluetoothLeAudio.AUDIO_LOCATION_TOP_SIDE_LEFT
218                     | BluetoothLeAudio.AUDIO_LOCATION_BOTTOM_FRONT_LEFT
219                     | BluetoothLeAudio.AUDIO_LOCATION_FRONT_LEFT_WIDE
220                     | BluetoothLeAudio.AUDIO_LOCATION_LEFT_SURROUND;
221 
222     private static final int LE_AUDIO_LOCATION_RIGHT =
223             BluetoothLeAudio.AUDIO_LOCATION_FRONT_RIGHT
224                     | BluetoothLeAudio.AUDIO_LOCATION_BACK_RIGHT
225                     | BluetoothLeAudio.AUDIO_LOCATION_FRONT_RIGHT_OF_CENTER
226                     | BluetoothLeAudio.AUDIO_LOCATION_SIDE_RIGHT
227                     | BluetoothLeAudio.AUDIO_LOCATION_TOP_FRONT_RIGHT
228                     | BluetoothLeAudio.AUDIO_LOCATION_TOP_BACK_RIGHT
229                     | BluetoothLeAudio.AUDIO_LOCATION_TOP_SIDE_RIGHT
230                     | BluetoothLeAudio.AUDIO_LOCATION_BOTTOM_FRONT_RIGHT
231                     | BluetoothLeAudio.AUDIO_LOCATION_FRONT_RIGHT_WIDE
232                     | BluetoothLeAudio.AUDIO_LOCATION_RIGHT_SURROUND;
233 
234     private static final SparseIntArray ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING;
235     private static final SparseIntArray ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING;
236     private static final SparseIntArray HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING;
237 
238     static {
239         ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING = new SparseIntArray();
ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING.put( HearingAidProfile.DeviceSide.SIDE_INVALID, DeviceSide.SIDE_INVALID)240         ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING.put(
241                 HearingAidProfile.DeviceSide.SIDE_INVALID, DeviceSide.SIDE_INVALID);
ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING.put( HearingAidProfile.DeviceSide.SIDE_LEFT, DeviceSide.SIDE_LEFT)242         ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING.put(
243                 HearingAidProfile.DeviceSide.SIDE_LEFT, DeviceSide.SIDE_LEFT);
ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING.put( HearingAidProfile.DeviceSide.SIDE_RIGHT, DeviceSide.SIDE_RIGHT)244         ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING.put(
245                 HearingAidProfile.DeviceSide.SIDE_RIGHT, DeviceSide.SIDE_RIGHT);
246 
247         ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING = new SparseIntArray();
ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING.put( HearingAidProfile.DeviceMode.MODE_INVALID, DeviceMode.MODE_INVALID)248         ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING.put(
249                 HearingAidProfile.DeviceMode.MODE_INVALID, DeviceMode.MODE_INVALID);
ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING.put( HearingAidProfile.DeviceMode.MODE_MONAURAL, DeviceMode.MODE_MONAURAL)250         ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING.put(
251                 HearingAidProfile.DeviceMode.MODE_MONAURAL, DeviceMode.MODE_MONAURAL);
ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING.put( HearingAidProfile.DeviceMode.MODE_BINAURAL, DeviceMode.MODE_BINAURAL)252         ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING.put(
253                 HearingAidProfile.DeviceMode.MODE_BINAURAL, DeviceMode.MODE_BINAURAL);
254 
255         HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING = new SparseIntArray();
HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put( HapClientProfile.HearingAidType.TYPE_INVALID, DeviceMode.MODE_INVALID)256         HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put(
257                 HapClientProfile.HearingAidType.TYPE_INVALID, DeviceMode.MODE_INVALID);
HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put( HapClientProfile.HearingAidType.TYPE_BINAURAL, DeviceMode.MODE_BINAURAL)258         HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put(
259                 HapClientProfile.HearingAidType.TYPE_BINAURAL, DeviceMode.MODE_BINAURAL);
HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put( HapClientProfile.HearingAidType.TYPE_MONAURAL, DeviceMode.MODE_MONAURAL)260         HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put(
261                 HapClientProfile.HearingAidType.TYPE_MONAURAL, DeviceMode.MODE_MONAURAL);
HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put( HapClientProfile.HearingAidType.TYPE_BANDED, DeviceMode.MODE_BANDED)262         HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put(
263                 HapClientProfile.HearingAidType.TYPE_BANDED, DeviceMode.MODE_BANDED);
HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put( HapClientProfile.HearingAidType.TYPE_RFU, DeviceMode.MODE_INVALID)264         HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put(
265                 HapClientProfile.HearingAidType.TYPE_RFU, DeviceMode.MODE_INVALID);
266 
267     }
268 }
269