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