• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 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.bluetooth.btservice.storage;
18 
19 import android.bluetooth.BluetoothA2dp;
20 import android.bluetooth.BluetoothA2dp.OptionalCodecsPreferenceStatus;
21 import android.bluetooth.BluetoothA2dp.OptionalCodecsSupportStatus;
22 import android.bluetooth.BluetoothDevice;
23 import android.bluetooth.BluetoothProfile;
24 import android.bluetooth.BluetoothUtils;
25 
26 import androidx.annotation.NonNull;
27 import androidx.room.Embedded;
28 import androidx.room.Entity;
29 import androidx.room.PrimaryKey;
30 
31 import com.android.internal.annotations.VisibleForTesting;
32 
33 import java.util.ArrayList;
34 import java.util.List;
35 
36 /**
37  * @hide
38  */
39 @Entity(tableName = "metadata")
40 @VisibleForTesting
41 public class Metadata {
42     @PrimaryKey
43     @NonNull
44     private String address;
45 
46     public boolean migrated;
47 
48     @Embedded
49     public ProfilePrioritiesEntity profileConnectionPolicies;
50 
51     @Embedded
52     @NonNull
53     public CustomizedMetadataEntity publicMetadata;
54 
55     public @OptionalCodecsSupportStatus int a2dpSupportsOptionalCodecs;
56     public @OptionalCodecsPreferenceStatus int a2dpOptionalCodecsEnabled;
57 
58     public long last_active_time;
59     public boolean is_active_a2dp_device;
60 
61     @Embedded
62     public AudioPolicyEntity audioPolicyMetadata;
63 
64     /**
65      * The preferred profile to be used for {@link BluetoothDevice#AUDIO_MODE_OUTPUT_ONLY}. This can
66      * be either {@link BluetoothProfile#A2DP} or {@link BluetoothProfile#LE_AUDIO}. This value is
67      * only used if the remote device supports both A2DP and LE Audio and both transports are
68      * connected and active.
69      */
70     public int preferred_output_only_profile;
71 
72     /**
73      * The preferred profile to be used for {@link BluetoothDevice#AUDIO_MODE_DUPLEX}. This can
74      * be either {@link BluetoothProfile#HEADSET} or {@link BluetoothProfile#LE_AUDIO}. This value
75      * is only used if the remote device supports both HFP and LE Audio and both transports are
76      * connected and active.
77      */
78     public int preferred_duplex_profile;
79 
Metadata(String address)80     Metadata(String address) {
81         this.address = address;
82         migrated = false;
83         profileConnectionPolicies = new ProfilePrioritiesEntity();
84         publicMetadata = new CustomizedMetadataEntity();
85         a2dpSupportsOptionalCodecs = BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN;
86         a2dpOptionalCodecsEnabled = BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN;
87         last_active_time = MetadataDatabase.sCurrentConnectionNumber++;
88         is_active_a2dp_device = true;
89         audioPolicyMetadata = new AudioPolicyEntity();
90         preferred_output_only_profile = 0;
91         preferred_duplex_profile = 0;
92     }
93 
94     /**
95      * @hide
96      */
97     @VisibleForTesting
getAddress()98     public String getAddress() {
99         return address;
100     }
101 
102     /**
103      * Returns the anonymized hardware address. The first three octets will be suppressed for
104      * anonymization.
105      * <p> For example, "XX:XX:XX:AA:BB:CC".
106      *
107      * @return Anonymized bluetooth hardware address as string
108      */
109     @NonNull
getAnonymizedAddress()110     public String getAnonymizedAddress() {
111         return BluetoothUtils.toAnonymizedAddress(address);
112     }
113 
setProfileConnectionPolicy(int profile, int connectionPolicy)114     void setProfileConnectionPolicy(int profile, int connectionPolicy) {
115         // We no longer support BluetoothProfile.PRIORITY_AUTO_CONNECT and are merging it into
116         // BluetoothProfile.CONNECTION_POLICY_ALLOWED
117         if (connectionPolicy > BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
118             connectionPolicy = BluetoothProfile.CONNECTION_POLICY_ALLOWED;
119         }
120 
121         switch (profile) {
122             case BluetoothProfile.A2DP:
123                 profileConnectionPolicies.a2dp_connection_policy = connectionPolicy;
124                 break;
125             case BluetoothProfile.A2DP_SINK:
126                 profileConnectionPolicies.a2dp_sink_connection_policy = connectionPolicy;
127                 break;
128             case BluetoothProfile.HEADSET:
129                 profileConnectionPolicies.hfp_connection_policy = connectionPolicy;
130                 break;
131             case BluetoothProfile.HEADSET_CLIENT:
132                 profileConnectionPolicies.hfp_client_connection_policy = connectionPolicy;
133                 break;
134             case BluetoothProfile.HID_HOST:
135                 profileConnectionPolicies.hid_host_connection_policy = connectionPolicy;
136                 break;
137             case BluetoothProfile.PAN:
138                 profileConnectionPolicies.pan_connection_policy = connectionPolicy;
139                 break;
140             case BluetoothProfile.PBAP:
141                 profileConnectionPolicies.pbap_connection_policy = connectionPolicy;
142                 break;
143             case BluetoothProfile.PBAP_CLIENT:
144                 profileConnectionPolicies.pbap_client_connection_policy = connectionPolicy;
145                 break;
146             case BluetoothProfile.MAP:
147                 profileConnectionPolicies.map_connection_policy = connectionPolicy;
148                 break;
149             case BluetoothProfile.MAP_CLIENT:
150                 profileConnectionPolicies.map_client_connection_policy = connectionPolicy;
151                 break;
152             case BluetoothProfile.SAP:
153                 profileConnectionPolicies.sap_connection_policy = connectionPolicy;
154                 break;
155             case BluetoothProfile.HEARING_AID:
156                 profileConnectionPolicies.hearing_aid_connection_policy = connectionPolicy;
157                 break;
158             case BluetoothProfile.HAP_CLIENT:
159                 profileConnectionPolicies.hap_client_connection_policy = connectionPolicy;
160                 break;
161             case BluetoothProfile.LE_AUDIO:
162                 profileConnectionPolicies.le_audio_connection_policy = connectionPolicy;
163                 break;
164             case BluetoothProfile.VOLUME_CONTROL:
165                 profileConnectionPolicies.volume_control_connection_policy = connectionPolicy;
166                 break;
167             case BluetoothProfile.CSIP_SET_COORDINATOR:
168                 profileConnectionPolicies.csip_set_coordinator_connection_policy = connectionPolicy;
169                 break;
170             case BluetoothProfile.LE_CALL_CONTROL:
171                 profileConnectionPolicies.le_call_control_connection_policy = connectionPolicy;
172                 break;
173             case BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT:
174                 profileConnectionPolicies.bass_client_connection_policy = connectionPolicy;
175                 break;
176             case BluetoothProfile.BATTERY:
177                 profileConnectionPolicies.battery_connection_policy = connectionPolicy;
178                 break;
179             default:
180                 throw new IllegalArgumentException("invalid profile " + profile);
181         }
182     }
183 
184     /**
185      * @hide
186      */
187     @VisibleForTesting
getProfileConnectionPolicy(int profile)188     public int getProfileConnectionPolicy(int profile) {
189         switch (profile) {
190             case BluetoothProfile.A2DP:
191                 return profileConnectionPolicies.a2dp_connection_policy;
192             case BluetoothProfile.A2DP_SINK:
193                 return profileConnectionPolicies.a2dp_sink_connection_policy;
194             case BluetoothProfile.HEADSET:
195                 return profileConnectionPolicies.hfp_connection_policy;
196             case BluetoothProfile.HEADSET_CLIENT:
197                 return profileConnectionPolicies.hfp_client_connection_policy;
198             case BluetoothProfile.HID_HOST:
199                 return profileConnectionPolicies.hid_host_connection_policy;
200             case BluetoothProfile.PAN:
201                 return profileConnectionPolicies.pan_connection_policy;
202             case BluetoothProfile.PBAP:
203                 return profileConnectionPolicies.pbap_connection_policy;
204             case BluetoothProfile.PBAP_CLIENT:
205                 return profileConnectionPolicies.pbap_client_connection_policy;
206             case BluetoothProfile.MAP:
207                 return profileConnectionPolicies.map_connection_policy;
208             case BluetoothProfile.MAP_CLIENT:
209                 return profileConnectionPolicies.map_client_connection_policy;
210             case BluetoothProfile.SAP:
211                 return profileConnectionPolicies.sap_connection_policy;
212             case BluetoothProfile.HEARING_AID:
213                 return profileConnectionPolicies.hearing_aid_connection_policy;
214             case BluetoothProfile.HAP_CLIENT:
215                 return profileConnectionPolicies.hap_client_connection_policy;
216             case BluetoothProfile.LE_AUDIO:
217                 return profileConnectionPolicies.le_audio_connection_policy;
218             case BluetoothProfile.VOLUME_CONTROL:
219                 return profileConnectionPolicies.volume_control_connection_policy;
220             case BluetoothProfile.CSIP_SET_COORDINATOR:
221                 return profileConnectionPolicies.csip_set_coordinator_connection_policy;
222             case BluetoothProfile.LE_CALL_CONTROL:
223                 return profileConnectionPolicies.le_call_control_connection_policy;
224             case BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT:
225                 return profileConnectionPolicies.bass_client_connection_policy;
226             case BluetoothProfile.BATTERY:
227                 return profileConnectionPolicies.battery_connection_policy;
228         }
229         return BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
230     }
231 
setCustomizedMeta(int key, byte[] value)232     void setCustomizedMeta(int key, byte[] value) {
233         switch (key) {
234             case BluetoothDevice.METADATA_MANUFACTURER_NAME:
235                 publicMetadata.manufacturer_name = value;
236                 break;
237             case BluetoothDevice.METADATA_MODEL_NAME:
238                 publicMetadata.model_name = value;
239                 break;
240             case BluetoothDevice.METADATA_SOFTWARE_VERSION:
241                 publicMetadata.software_version = value;
242                 break;
243             case BluetoothDevice.METADATA_HARDWARE_VERSION:
244                 publicMetadata.hardware_version = value;
245                 break;
246             case BluetoothDevice.METADATA_COMPANION_APP:
247                 publicMetadata.companion_app = value;
248                 break;
249             case BluetoothDevice.METADATA_MAIN_ICON:
250                 publicMetadata.main_icon = value;
251                 break;
252             case BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET:
253                 publicMetadata.is_untethered_headset = value;
254                 break;
255             case BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON:
256                 publicMetadata.untethered_left_icon = value;
257                 break;
258             case BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON:
259                 publicMetadata.untethered_right_icon = value;
260                 break;
261             case BluetoothDevice.METADATA_UNTETHERED_CASE_ICON:
262                 publicMetadata.untethered_case_icon = value;
263                 break;
264             case BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY:
265                 publicMetadata.untethered_left_battery = value;
266                 break;
267             case BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY:
268                 publicMetadata.untethered_right_battery = value;
269                 break;
270             case BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY:
271                 publicMetadata.untethered_case_battery = value;
272                 break;
273             case BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING:
274                 publicMetadata.untethered_left_charging = value;
275                 break;
276             case BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING:
277                 publicMetadata.untethered_right_charging = value;
278                 break;
279             case BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING:
280                 publicMetadata.untethered_case_charging = value;
281                 break;
282             case BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI:
283                 publicMetadata.enhanced_settings_ui_uri = value;
284                 break;
285             case BluetoothDevice.METADATA_DEVICE_TYPE:
286                 publicMetadata.device_type = value;
287                 break;
288             case BluetoothDevice.METADATA_MAIN_BATTERY:
289                 publicMetadata.main_battery = value;
290                 break;
291             case BluetoothDevice.METADATA_MAIN_CHARGING:
292                 publicMetadata.main_charging = value;
293                 break;
294             case BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD:
295                 publicMetadata.main_low_battery_threshold = value;
296                 break;
297             case BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD:
298                 publicMetadata.untethered_left_low_battery_threshold = value;
299                 break;
300             case BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD:
301                 publicMetadata.untethered_right_low_battery_threshold = value;
302                 break;
303             case BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD:
304                 publicMetadata.untethered_case_low_battery_threshold = value;
305                 break;
306             case BluetoothDevice.METADATA_SPATIAL_AUDIO:
307                 publicMetadata.spatial_audio = value;
308                 break;
309             case BluetoothDevice.METADATA_FAST_PAIR_CUSTOMIZED_FIELDS:
310                 publicMetadata.fastpair_customized = value;
311                 break;
312             case BluetoothDevice.METADATA_LE_AUDIO:
313                 publicMetadata.le_audio = value;
314                 break;
315             case BluetoothDevice.METADATA_GMCS_CCCD:
316                 publicMetadata.gmcs_cccd = value;
317                 break;
318             case BluetoothDevice.METADATA_GTBS_CCCD:
319                 publicMetadata.gtbs_cccd = value;
320                 break;
321         }
322     }
323 
324     /**
325      * @hide
326      */
327     @VisibleForTesting
getCustomizedMeta(int key)328     public byte[] getCustomizedMeta(int key) {
329         byte[] value = null;
330         switch (key) {
331             case BluetoothDevice.METADATA_MANUFACTURER_NAME:
332                 value = publicMetadata.manufacturer_name;
333                 break;
334             case BluetoothDevice.METADATA_MODEL_NAME:
335                 value = publicMetadata.model_name;
336                 break;
337             case BluetoothDevice.METADATA_SOFTWARE_VERSION:
338                 value = publicMetadata.software_version;
339                 break;
340             case BluetoothDevice.METADATA_HARDWARE_VERSION:
341                 value = publicMetadata.hardware_version;
342                 break;
343             case BluetoothDevice.METADATA_COMPANION_APP:
344                 value = publicMetadata.companion_app;
345                 break;
346             case BluetoothDevice.METADATA_MAIN_ICON:
347                 value = publicMetadata.main_icon;
348                 break;
349             case BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET:
350                 value = publicMetadata.is_untethered_headset;
351                 break;
352             case BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON:
353                 value = publicMetadata.untethered_left_icon;
354                 break;
355             case BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON:
356                 value = publicMetadata.untethered_right_icon;
357                 break;
358             case BluetoothDevice.METADATA_UNTETHERED_CASE_ICON:
359                 value = publicMetadata.untethered_case_icon;
360                 break;
361             case BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY:
362                 value = publicMetadata.untethered_left_battery;
363                 break;
364             case BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY:
365                 value = publicMetadata.untethered_right_battery;
366                 break;
367             case BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY:
368                 value = publicMetadata.untethered_case_battery;
369                 break;
370             case BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING:
371                 value = publicMetadata.untethered_left_charging;
372                 break;
373             case BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING:
374                 value = publicMetadata.untethered_right_charging;
375                 break;
376             case BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING:
377                 value = publicMetadata.untethered_case_charging;
378                 break;
379             case BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI:
380                 value = publicMetadata.enhanced_settings_ui_uri;
381                 break;
382             case BluetoothDevice.METADATA_DEVICE_TYPE:
383                 value = publicMetadata.device_type;
384                 break;
385             case BluetoothDevice.METADATA_MAIN_BATTERY:
386                 value = publicMetadata.main_battery;
387                 break;
388             case BluetoothDevice.METADATA_MAIN_CHARGING:
389                 value = publicMetadata.main_charging;
390                 break;
391             case BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD:
392                 value = publicMetadata.main_low_battery_threshold;
393                 break;
394             case BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD:
395                 value = publicMetadata.untethered_left_low_battery_threshold;
396                 break;
397             case BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD:
398                 value = publicMetadata.untethered_right_low_battery_threshold;
399                 break;
400             case BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD:
401                 value = publicMetadata.untethered_case_low_battery_threshold;
402                 break;
403             case BluetoothDevice.METADATA_SPATIAL_AUDIO:
404                 value = publicMetadata.spatial_audio;
405                 break;
406             case BluetoothDevice.METADATA_FAST_PAIR_CUSTOMIZED_FIELDS:
407                 value = publicMetadata.fastpair_customized;
408                 break;
409             case BluetoothDevice.METADATA_LE_AUDIO:
410                 value = publicMetadata.le_audio;
411                 break;
412             case BluetoothDevice.METADATA_GMCS_CCCD:
413                 value = publicMetadata.gmcs_cccd;
414                 break;
415             case BluetoothDevice.METADATA_GTBS_CCCD:
416                 value = publicMetadata.gtbs_cccd;
417                 break;
418         }
419         return value;
420     }
421 
getChangedCustomizedMeta()422     List<Integer> getChangedCustomizedMeta() {
423         List<Integer> list = new ArrayList<>();
424         for (int key = 0; key <= BluetoothDevice.getMaxMetadataKey(); key++) {
425             if (getCustomizedMeta(key) != null) {
426                 list.add(key);
427             }
428         }
429         return list;
430     }
431 
toString()432     public String toString() {
433         StringBuilder builder = new StringBuilder();
434         builder.append(getAnonymizedAddress())
435             .append(" last_active_time=" + last_active_time)
436             .append(" {profile connection policy(")
437             .append(profileConnectionPolicies)
438             .append("), optional codec(support=")
439             .append(a2dpSupportsOptionalCodecs)
440             .append("|enabled=")
441             .append(a2dpOptionalCodecsEnabled)
442             .append("), custom metadata(")
443             .append(publicMetadata)
444             .append("), hfp client audio policy(")
445             .append(audioPolicyMetadata)
446             .append(")}");
447 
448         return builder.toString();
449     }
450 }
451