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 25 import androidx.annotation.NonNull; 26 import androidx.room.Embedded; 27 import androidx.room.Entity; 28 import androidx.room.PrimaryKey; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 33 @Entity(tableName = "metadata") 34 class Metadata { 35 @PrimaryKey 36 @NonNull 37 private String address; 38 39 public boolean migrated; 40 41 @Embedded 42 public ProfilePrioritiesEntity profileConnectionPolicies; 43 44 @Embedded 45 @NonNull 46 public CustomizedMetadataEntity publicMetadata; 47 48 public @OptionalCodecsSupportStatus int a2dpSupportsOptionalCodecs; 49 public @OptionalCodecsPreferenceStatus int a2dpOptionalCodecsEnabled; 50 51 public long last_active_time; 52 public boolean is_active_a2dp_device; 53 Metadata(String address)54 Metadata(String address) { 55 this.address = address; 56 migrated = false; 57 profileConnectionPolicies = new ProfilePrioritiesEntity(); 58 publicMetadata = new CustomizedMetadataEntity(); 59 a2dpSupportsOptionalCodecs = BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN; 60 a2dpOptionalCodecsEnabled = BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN; 61 last_active_time = MetadataDatabase.sCurrentConnectionNumber++; 62 is_active_a2dp_device = true; 63 } 64 getAddress()65 String getAddress() { 66 return address; 67 } 68 setProfileConnectionPolicy(int profile, int connectionPolicy)69 void setProfileConnectionPolicy(int profile, int connectionPolicy) { 70 // We no longer support BluetoothProfile.PRIORITY_AUTO_CONNECT and are merging it into 71 // BluetoothProfile.CONNECTION_POLICY_ALLOWED 72 if (connectionPolicy > BluetoothProfile.CONNECTION_POLICY_ALLOWED) { 73 connectionPolicy = BluetoothProfile.CONNECTION_POLICY_ALLOWED; 74 } 75 76 switch (profile) { 77 case BluetoothProfile.A2DP: 78 profileConnectionPolicies.a2dp_connection_policy = connectionPolicy; 79 break; 80 case BluetoothProfile.A2DP_SINK: 81 profileConnectionPolicies.a2dp_sink_connection_policy = connectionPolicy; 82 break; 83 case BluetoothProfile.HEADSET: 84 profileConnectionPolicies.hfp_connection_policy = connectionPolicy; 85 break; 86 case BluetoothProfile.HEADSET_CLIENT: 87 profileConnectionPolicies.hfp_client_connection_policy = connectionPolicy; 88 break; 89 case BluetoothProfile.HID_HOST: 90 profileConnectionPolicies.hid_host_connection_policy = connectionPolicy; 91 break; 92 case BluetoothProfile.PAN: 93 profileConnectionPolicies.pan_connection_policy = connectionPolicy; 94 break; 95 case BluetoothProfile.PBAP: 96 profileConnectionPolicies.pbap_connection_policy = connectionPolicy; 97 break; 98 case BluetoothProfile.PBAP_CLIENT: 99 profileConnectionPolicies.pbap_client_connection_policy = connectionPolicy; 100 break; 101 case BluetoothProfile.MAP: 102 profileConnectionPolicies.map_connection_policy = connectionPolicy; 103 break; 104 case BluetoothProfile.MAP_CLIENT: 105 profileConnectionPolicies.map_client_connection_policy = connectionPolicy; 106 break; 107 case BluetoothProfile.SAP: 108 profileConnectionPolicies.sap_connection_policy = connectionPolicy; 109 break; 110 case BluetoothProfile.HEARING_AID: 111 profileConnectionPolicies.hearing_aid_connection_policy = connectionPolicy; 112 break; 113 case BluetoothProfile.LE_AUDIO: 114 profileConnectionPolicies.le_audio_connection_policy = connectionPolicy; 115 break; 116 default: 117 throw new IllegalArgumentException("invalid profile " + profile); 118 } 119 } 120 getProfileConnectionPolicy(int profile)121 int getProfileConnectionPolicy(int profile) { 122 switch (profile) { 123 case BluetoothProfile.A2DP: 124 return profileConnectionPolicies.a2dp_connection_policy; 125 case BluetoothProfile.A2DP_SINK: 126 return profileConnectionPolicies.a2dp_sink_connection_policy; 127 case BluetoothProfile.HEADSET: 128 return profileConnectionPolicies.hfp_connection_policy; 129 case BluetoothProfile.HEADSET_CLIENT: 130 return profileConnectionPolicies.hfp_client_connection_policy; 131 case BluetoothProfile.HID_HOST: 132 return profileConnectionPolicies.hid_host_connection_policy; 133 case BluetoothProfile.PAN: 134 return profileConnectionPolicies.pan_connection_policy; 135 case BluetoothProfile.PBAP: 136 return profileConnectionPolicies.pbap_connection_policy; 137 case BluetoothProfile.PBAP_CLIENT: 138 return profileConnectionPolicies.pbap_client_connection_policy; 139 case BluetoothProfile.MAP: 140 return profileConnectionPolicies.map_connection_policy; 141 case BluetoothProfile.MAP_CLIENT: 142 return profileConnectionPolicies.map_client_connection_policy; 143 case BluetoothProfile.SAP: 144 return profileConnectionPolicies.sap_connection_policy; 145 case BluetoothProfile.HEARING_AID: 146 return profileConnectionPolicies.hearing_aid_connection_policy; 147 case BluetoothProfile.LE_AUDIO: 148 return profileConnectionPolicies.le_audio_connection_policy; 149 } 150 return BluetoothProfile.CONNECTION_POLICY_UNKNOWN; 151 } 152 setCustomizedMeta(int key, byte[] value)153 void setCustomizedMeta(int key, byte[] value) { 154 switch (key) { 155 case BluetoothDevice.METADATA_MANUFACTURER_NAME: 156 publicMetadata.manufacturer_name = value; 157 break; 158 case BluetoothDevice.METADATA_MODEL_NAME: 159 publicMetadata.model_name = value; 160 break; 161 case BluetoothDevice.METADATA_SOFTWARE_VERSION: 162 publicMetadata.software_version = value; 163 break; 164 case BluetoothDevice.METADATA_HARDWARE_VERSION: 165 publicMetadata.hardware_version = value; 166 break; 167 case BluetoothDevice.METADATA_COMPANION_APP: 168 publicMetadata.companion_app = value; 169 break; 170 case BluetoothDevice.METADATA_MAIN_ICON: 171 publicMetadata.main_icon = value; 172 break; 173 case BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET: 174 publicMetadata.is_untethered_headset = value; 175 break; 176 case BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON: 177 publicMetadata.untethered_left_icon = value; 178 break; 179 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON: 180 publicMetadata.untethered_right_icon = value; 181 break; 182 case BluetoothDevice.METADATA_UNTETHERED_CASE_ICON: 183 publicMetadata.untethered_case_icon = value; 184 break; 185 case BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY: 186 publicMetadata.untethered_left_battery = value; 187 break; 188 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY: 189 publicMetadata.untethered_right_battery = value; 190 break; 191 case BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY: 192 publicMetadata.untethered_case_battery = value; 193 break; 194 case BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING: 195 publicMetadata.untethered_left_charging = value; 196 break; 197 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING: 198 publicMetadata.untethered_right_charging = value; 199 break; 200 case BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING: 201 publicMetadata.untethered_case_charging = value; 202 break; 203 case BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI: 204 publicMetadata.enhanced_settings_ui_uri = value; 205 break; 206 case BluetoothDevice.METADATA_DEVICE_TYPE: 207 publicMetadata.device_type = value; 208 break; 209 case BluetoothDevice.METADATA_MAIN_BATTERY: 210 publicMetadata.main_battery = value; 211 break; 212 case BluetoothDevice.METADATA_MAIN_CHARGING: 213 publicMetadata.main_charging = value; 214 break; 215 case BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD: 216 publicMetadata.main_low_battery_threshold = value; 217 break; 218 case BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD: 219 publicMetadata.untethered_left_low_battery_threshold = value; 220 break; 221 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD: 222 publicMetadata.untethered_right_low_battery_threshold = value; 223 break; 224 case BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD: 225 publicMetadata.untethered_case_low_battery_threshold = value; 226 break; 227 } 228 } 229 getCustomizedMeta(int key)230 byte[] getCustomizedMeta(int key) { 231 byte[] value = null; 232 switch (key) { 233 case BluetoothDevice.METADATA_MANUFACTURER_NAME: 234 value = publicMetadata.manufacturer_name; 235 break; 236 case BluetoothDevice.METADATA_MODEL_NAME: 237 value = publicMetadata.model_name; 238 break; 239 case BluetoothDevice.METADATA_SOFTWARE_VERSION: 240 value = publicMetadata.software_version; 241 break; 242 case BluetoothDevice.METADATA_HARDWARE_VERSION: 243 value = publicMetadata.hardware_version; 244 break; 245 case BluetoothDevice.METADATA_COMPANION_APP: 246 value = publicMetadata.companion_app; 247 break; 248 case BluetoothDevice.METADATA_MAIN_ICON: 249 value = publicMetadata.main_icon; 250 break; 251 case BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET: 252 value = publicMetadata.is_untethered_headset; 253 break; 254 case BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON: 255 value = publicMetadata.untethered_left_icon; 256 break; 257 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON: 258 value = publicMetadata.untethered_right_icon; 259 break; 260 case BluetoothDevice.METADATA_UNTETHERED_CASE_ICON: 261 value = publicMetadata.untethered_case_icon; 262 break; 263 case BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY: 264 value = publicMetadata.untethered_left_battery; 265 break; 266 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY: 267 value = publicMetadata.untethered_right_battery; 268 break; 269 case BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY: 270 value = publicMetadata.untethered_case_battery; 271 break; 272 case BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING: 273 value = publicMetadata.untethered_left_charging; 274 break; 275 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING: 276 value = publicMetadata.untethered_right_charging; 277 break; 278 case BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING: 279 value = publicMetadata.untethered_case_charging; 280 break; 281 case BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI: 282 value = publicMetadata.enhanced_settings_ui_uri; 283 break; 284 case BluetoothDevice.METADATA_DEVICE_TYPE: 285 value = publicMetadata.device_type; 286 break; 287 case BluetoothDevice.METADATA_MAIN_BATTERY: 288 value = publicMetadata.main_battery; 289 break; 290 case BluetoothDevice.METADATA_MAIN_CHARGING: 291 value = publicMetadata.main_charging; 292 break; 293 case BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD: 294 value = publicMetadata.main_low_battery_threshold; 295 break; 296 case BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD: 297 value = publicMetadata.untethered_left_low_battery_threshold; 298 break; 299 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD: 300 value = publicMetadata.untethered_right_low_battery_threshold; 301 break; 302 case BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD: 303 value = publicMetadata.untethered_case_low_battery_threshold; 304 break; 305 } 306 return value; 307 } 308 getChangedCustomizedMeta()309 List<Integer> getChangedCustomizedMeta() { 310 List<Integer> list = new ArrayList<>(); 311 for (int key = 0; key <= BluetoothDevice.getMaxMetadataKey(); key++) { 312 if (getCustomizedMeta(key) != null) { 313 list.add(key); 314 } 315 } 316 return list; 317 } 318 toString()319 public String toString() { 320 StringBuilder builder = new StringBuilder(); 321 builder.append(address) 322 .append(" {profile connection policy(") 323 .append(profileConnectionPolicies) 324 .append("), optional codec(support=") 325 .append(a2dpSupportsOptionalCodecs) 326 .append("|enabled=") 327 .append(a2dpOptionalCodecsEnabled) 328 .append("), custom metadata(") 329 .append(publicMetadata) 330 .append(")}"); 331 332 return builder.toString(); 333 } 334 } 335