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 default: 114 throw new IllegalArgumentException("invalid profile " + profile); 115 } 116 } 117 getProfileConnectionPolicy(int profile)118 int getProfileConnectionPolicy(int profile) { 119 switch (profile) { 120 case BluetoothProfile.A2DP: 121 return profileConnectionPolicies.a2dp_connection_policy; 122 case BluetoothProfile.A2DP_SINK: 123 return profileConnectionPolicies.a2dp_sink_connection_policy; 124 case BluetoothProfile.HEADSET: 125 return profileConnectionPolicies.hfp_connection_policy; 126 case BluetoothProfile.HEADSET_CLIENT: 127 return profileConnectionPolicies.hfp_client_connection_policy; 128 case BluetoothProfile.HID_HOST: 129 return profileConnectionPolicies.hid_host_connection_policy; 130 case BluetoothProfile.PAN: 131 return profileConnectionPolicies.pan_connection_policy; 132 case BluetoothProfile.PBAP: 133 return profileConnectionPolicies.pbap_connection_policy; 134 case BluetoothProfile.PBAP_CLIENT: 135 return profileConnectionPolicies.pbap_client_connection_policy; 136 case BluetoothProfile.MAP: 137 return profileConnectionPolicies.map_connection_policy; 138 case BluetoothProfile.MAP_CLIENT: 139 return profileConnectionPolicies.map_client_connection_policy; 140 case BluetoothProfile.SAP: 141 return profileConnectionPolicies.sap_connection_policy; 142 case BluetoothProfile.HEARING_AID: 143 return profileConnectionPolicies.hearing_aid_connection_policy; 144 } 145 return BluetoothProfile.CONNECTION_POLICY_UNKNOWN; 146 } 147 setCustomizedMeta(int key, byte[] value)148 void setCustomizedMeta(int key, byte[] value) { 149 switch (key) { 150 case BluetoothDevice.METADATA_MANUFACTURER_NAME: 151 publicMetadata.manufacturer_name = value; 152 break; 153 case BluetoothDevice.METADATA_MODEL_NAME: 154 publicMetadata.model_name = value; 155 break; 156 case BluetoothDevice.METADATA_SOFTWARE_VERSION: 157 publicMetadata.software_version = value; 158 break; 159 case BluetoothDevice.METADATA_HARDWARE_VERSION: 160 publicMetadata.hardware_version = value; 161 break; 162 case BluetoothDevice.METADATA_COMPANION_APP: 163 publicMetadata.companion_app = value; 164 break; 165 case BluetoothDevice.METADATA_MAIN_ICON: 166 publicMetadata.main_icon = value; 167 break; 168 case BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET: 169 publicMetadata.is_untethered_headset = value; 170 break; 171 case BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON: 172 publicMetadata.untethered_left_icon = value; 173 break; 174 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON: 175 publicMetadata.untethered_right_icon = value; 176 break; 177 case BluetoothDevice.METADATA_UNTETHERED_CASE_ICON: 178 publicMetadata.untethered_case_icon = value; 179 break; 180 case BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY: 181 publicMetadata.untethered_left_battery = value; 182 break; 183 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY: 184 publicMetadata.untethered_right_battery = value; 185 break; 186 case BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY: 187 publicMetadata.untethered_case_battery = value; 188 break; 189 case BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING: 190 publicMetadata.untethered_left_charging = value; 191 break; 192 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING: 193 publicMetadata.untethered_right_charging = value; 194 break; 195 case BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING: 196 publicMetadata.untethered_case_charging = value; 197 break; 198 case BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI: 199 publicMetadata.enhanced_settings_ui_uri = value; 200 break; 201 } 202 } 203 getCustomizedMeta(int key)204 byte[] getCustomizedMeta(int key) { 205 byte[] value = null; 206 switch (key) { 207 case BluetoothDevice.METADATA_MANUFACTURER_NAME: 208 value = publicMetadata.manufacturer_name; 209 break; 210 case BluetoothDevice.METADATA_MODEL_NAME: 211 value = publicMetadata.model_name; 212 break; 213 case BluetoothDevice.METADATA_SOFTWARE_VERSION: 214 value = publicMetadata.software_version; 215 break; 216 case BluetoothDevice.METADATA_HARDWARE_VERSION: 217 value = publicMetadata.hardware_version; 218 break; 219 case BluetoothDevice.METADATA_COMPANION_APP: 220 value = publicMetadata.companion_app; 221 break; 222 case BluetoothDevice.METADATA_MAIN_ICON: 223 value = publicMetadata.main_icon; 224 break; 225 case BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET: 226 value = publicMetadata.is_untethered_headset; 227 break; 228 case BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON: 229 value = publicMetadata.untethered_left_icon; 230 break; 231 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON: 232 value = publicMetadata.untethered_right_icon; 233 break; 234 case BluetoothDevice.METADATA_UNTETHERED_CASE_ICON: 235 value = publicMetadata.untethered_case_icon; 236 break; 237 case BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY: 238 value = publicMetadata.untethered_left_battery; 239 break; 240 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY: 241 value = publicMetadata.untethered_right_battery; 242 break; 243 case BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY: 244 value = publicMetadata.untethered_case_battery; 245 break; 246 case BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING: 247 value = publicMetadata.untethered_left_charging; 248 break; 249 case BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING: 250 value = publicMetadata.untethered_right_charging; 251 break; 252 case BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING: 253 value = publicMetadata.untethered_case_charging; 254 break; 255 case BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI: 256 value = publicMetadata.enhanced_settings_ui_uri; 257 break; 258 } 259 return value; 260 } 261 getChangedCustomizedMeta()262 List<Integer> getChangedCustomizedMeta() { 263 List<Integer> list = new ArrayList<>(); 264 if (publicMetadata.manufacturer_name != null) { 265 list.add(BluetoothDevice.METADATA_MANUFACTURER_NAME); 266 } 267 if (publicMetadata.model_name != null) { 268 list.add(BluetoothDevice.METADATA_MODEL_NAME); 269 } 270 if (publicMetadata.software_version != null) { 271 list.add(BluetoothDevice.METADATA_SOFTWARE_VERSION); 272 } 273 if (publicMetadata.hardware_version != null) { 274 list.add(BluetoothDevice.METADATA_HARDWARE_VERSION); 275 } 276 if (publicMetadata.companion_app != null) { 277 list.add(BluetoothDevice.METADATA_COMPANION_APP); 278 } 279 if (publicMetadata.main_icon != null) { 280 list.add(BluetoothDevice.METADATA_MAIN_ICON); 281 } 282 if (publicMetadata.is_untethered_headset != null) { 283 list.add(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET); 284 } 285 if (publicMetadata.untethered_left_icon != null) { 286 list.add(BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON); 287 } 288 if (publicMetadata.untethered_right_icon != null) { 289 list.add(BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON); 290 } 291 if (publicMetadata.untethered_case_icon != null) { 292 list.add(BluetoothDevice.METADATA_UNTETHERED_CASE_ICON); 293 } 294 if (publicMetadata.untethered_left_battery != null) { 295 list.add(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY); 296 } 297 if (publicMetadata.untethered_right_battery != null) { 298 list.add(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY); 299 } 300 if (publicMetadata.untethered_case_battery != null) { 301 list.add(BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY); 302 } 303 if (publicMetadata.untethered_left_charging != null) { 304 list.add(BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING); 305 } 306 if (publicMetadata.untethered_right_charging != null) { 307 list.add(BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING); 308 } 309 if (publicMetadata.untethered_case_charging != null) { 310 list.add(BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING); 311 } 312 if (publicMetadata.enhanced_settings_ui_uri != null) { 313 list.add(BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI); 314 } 315 return list; 316 } 317 toString()318 public String toString() { 319 StringBuilder builder = new StringBuilder(); 320 builder.append(address) 321 .append(" {profile connection policy(") 322 .append(profileConnectionPolicies) 323 .append("), optional codec(support=") 324 .append(a2dpSupportsOptionalCodecs) 325 .append("|enabled=") 326 .append(a2dpOptionalCodecsEnabled) 327 .append("), custom metadata(") 328 .append(publicMetadata) 329 .append(")}"); 330 331 return builder.toString(); 332 } 333 } 334