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 static org.junit.Assert.assertThat; 20 import static org.mockito.ArgumentMatchers.any; 21 import static org.mockito.ArgumentMatchers.anyInt; 22 import static org.mockito.ArgumentMatchers.anyString; 23 import static org.mockito.Mockito.doNothing; 24 import static org.mockito.Mockito.doReturn; 25 import static org.mockito.Mockito.times; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.when; 28 29 import android.bluetooth.BluetoothA2dp; 30 import android.bluetooth.BluetoothAdapter; 31 import android.bluetooth.BluetoothDevice; 32 import android.bluetooth.BluetoothProfile; 33 import android.content.ContentValues; 34 import android.database.Cursor; 35 import android.database.sqlite.SQLiteDatabase; 36 37 import androidx.room.Room; 38 import androidx.room.testing.MigrationTestHelper; 39 import androidx.sqlite.db.SupportSQLiteDatabase; 40 import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory; 41 import androidx.test.InstrumentationRegistry; 42 import androidx.test.filters.MediumTest; 43 import androidx.test.runner.AndroidJUnit4; 44 45 import com.android.bluetooth.TestUtils; 46 import com.android.bluetooth.btservice.AdapterService; 47 48 import org.hamcrest.CoreMatchers; 49 import org.junit.After; 50 import org.junit.Assert; 51 import org.junit.Before; 52 import org.junit.Rule; 53 import org.junit.Test; 54 import org.junit.runner.RunWith; 55 import org.mockito.Mock; 56 import org.mockito.MockitoAnnotations; 57 58 import java.io.IOException; 59 import java.util.List; 60 61 @MediumTest 62 @RunWith(AndroidJUnit4.class) 63 public final class DatabaseManagerTest { 64 65 @Mock private AdapterService mAdapterService; 66 67 private MetadataDatabase mDatabase; 68 private DatabaseManager mDatabaseManager; 69 private BluetoothDevice mTestDevice; 70 private BluetoothDevice mTestDevice2; 71 private BluetoothDevice mTestDevice3; 72 73 private static final String LOCAL_STORAGE = "LocalStorage"; 74 private static final String TEST_BT_ADDR = "11:22:33:44:55:66"; 75 private static final String TEST_BT_ADDR2 = "66:55:44:33:22:11"; 76 private static final String TEST_BT_ADDR3 = "12:34:56:65:43:21"; 77 private static final String OTHER_BT_ADDR1 = "11:11:11:11:11:11"; 78 private static final String OTHER_BT_ADDR2 = "22:22:22:22:22:22"; 79 private static final String DB_NAME = "test_db"; 80 private static final int A2DP_SUPPORT_OP_CODEC_TEST = 0; 81 private static final int A2DP_ENALBED_OP_CODEC_TEST = 1; 82 private static final int MAX_META_ID = 16; 83 private static final byte[] TEST_BYTE_ARRAY = "TEST_VALUE".getBytes(); 84 85 @Rule 86 public MigrationTestHelper testHelper = new MigrationTestHelper( 87 InstrumentationRegistry.getInstrumentation(), 88 MetadataDatabase.class.getCanonicalName(), 89 new FrameworkSQLiteOpenHelperFactory()); 90 @Before setUp()91 public void setUp() throws Exception { 92 MockitoAnnotations.initMocks(this); 93 TestUtils.setAdapterService(mAdapterService); 94 95 mTestDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_BT_ADDR); 96 mTestDevice2 = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_BT_ADDR2); 97 mTestDevice3 = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_BT_ADDR3); 98 99 // Create a memory database for DatabaseManager instead of use a real database. 100 mDatabase = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getTargetContext(), 101 MetadataDatabase.class).build(); 102 103 when(mAdapterService.getPackageManager()).thenReturn( 104 InstrumentationRegistry.getTargetContext().getPackageManager()); 105 mDatabaseManager = new DatabaseManager(mAdapterService); 106 107 BluetoothDevice[] bondedDevices = {mTestDevice}; 108 doReturn(bondedDevices).when(mAdapterService).getBondedDevices(); 109 doNothing().when(mAdapterService).metadataChanged( 110 anyString(), anyInt(), any(byte[].class)); 111 112 restartDatabaseManagerHelper(); 113 } 114 115 @After tearDown()116 public void tearDown() throws Exception { 117 TestUtils.clearAdapterService(mAdapterService); 118 mDatabase.deleteAll(); 119 mDatabaseManager.cleanup(); 120 } 121 122 @Test testMetadataDefault()123 public void testMetadataDefault() { 124 Metadata data = new Metadata(TEST_BT_ADDR); 125 mDatabase.insert(data); 126 restartDatabaseManagerHelper(); 127 128 for (int id = 0; id < BluetoothProfile.MAX_PROFILE_ID; id++) { 129 Assert.assertEquals(BluetoothProfile.CONNECTION_POLICY_UNKNOWN, 130 mDatabaseManager.getProfileConnectionPolicy(mTestDevice, id)); 131 } 132 133 Assert.assertEquals(BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, 134 mDatabaseManager.getA2dpSupportsOptionalCodecs(mTestDevice)); 135 136 Assert.assertEquals(BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, 137 mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice)); 138 139 for (int id = 0; id < MAX_META_ID; id++) { 140 Assert.assertNull(mDatabaseManager.getCustomMeta(mTestDevice, id)); 141 } 142 143 mDatabaseManager.factoryReset(); 144 mDatabaseManager.mMetadataCache.clear(); 145 // Wait for clear database 146 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 147 } 148 149 @Test testSetGetProfileConnectionPolicy()150 public void testSetGetProfileConnectionPolicy() { 151 int badConnectionPolicy = -100; 152 153 // Cases of device not in database 154 testSetGetProfileConnectionPolicyCase(false, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, 155 BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true); 156 testSetGetProfileConnectionPolicyCase(false, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, 157 BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, true); 158 testSetGetProfileConnectionPolicyCase(false, BluetoothProfile.CONNECTION_POLICY_ALLOWED, 159 BluetoothProfile.CONNECTION_POLICY_ALLOWED, true); 160 testSetGetProfileConnectionPolicyCase(false, badConnectionPolicy, 161 BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); 162 163 // Cases of device already in database 164 testSetGetProfileConnectionPolicyCase(true, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, 165 BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true); 166 testSetGetProfileConnectionPolicyCase(true, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, 167 BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, true); 168 testSetGetProfileConnectionPolicyCase(true, BluetoothProfile.CONNECTION_POLICY_ALLOWED, 169 BluetoothProfile.CONNECTION_POLICY_ALLOWED, true); 170 testSetGetProfileConnectionPolicyCase(true, badConnectionPolicy, 171 BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); 172 } 173 174 @Test testSetGetA2dpSupportsOptionalCodecs()175 public void testSetGetA2dpSupportsOptionalCodecs() { 176 int badValue = -100; 177 178 // Cases of device not in database 179 testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false, 180 BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, 181 BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); 182 testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false, 183 BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, 184 BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); 185 testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false, 186 BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, 187 BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); 188 testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false, 189 badValue, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); 190 191 // Cases of device already in database 192 testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, true, 193 BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, 194 BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); 195 testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, true, 196 BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, 197 BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED); 198 testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, true, 199 BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, 200 BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED); 201 testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, true, 202 badValue, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); 203 } 204 205 @Test testSetGetA2dpOptionalCodecsEnabled()206 public void testSetGetA2dpOptionalCodecsEnabled() { 207 int badValue = -100; 208 209 // Cases of device not in database 210 testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false, 211 BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, 212 BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); 213 testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false, 214 BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, 215 BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); 216 testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false, 217 BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED, 218 BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); 219 testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false, 220 badValue, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); 221 222 // Cases of device already in database 223 testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, true, 224 BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, 225 BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); 226 testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, true, 227 BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, 228 BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED); 229 testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, true, 230 BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED, 231 BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); 232 testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, true, 233 badValue, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); 234 } 235 236 @Test testRemoveUnusedMetadata_WithSingleBondedDevice()237 public void testRemoveUnusedMetadata_WithSingleBondedDevice() { 238 // Insert two devices to database and cache, only mTestDevice is 239 // in the bonded list 240 Metadata otherData = new Metadata(OTHER_BT_ADDR1); 241 // Add metadata for otherDevice 242 otherData.setCustomizedMeta(0, TEST_BYTE_ARRAY); 243 mDatabaseManager.mMetadataCache.put(OTHER_BT_ADDR1, otherData); 244 mDatabase.insert(otherData); 245 246 Metadata data = new Metadata(TEST_BT_ADDR); 247 mDatabaseManager.mMetadataCache.put(TEST_BT_ADDR, data); 248 mDatabase.insert(data); 249 250 mDatabaseManager.removeUnusedMetadata(); 251 // Wait for database update 252 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 253 254 // Check removed device report metadata changed to null 255 verify(mAdapterService).metadataChanged(OTHER_BT_ADDR1, 0, null); 256 257 List<Metadata> list = mDatabase.load(); 258 259 // Check number of metadata in the database 260 Assert.assertEquals(1, list.size()); 261 262 // Check whether the device is in database 263 Metadata checkData = list.get(0); 264 Assert.assertEquals(TEST_BT_ADDR, checkData.getAddress()); 265 266 mDatabaseManager.factoryReset(); 267 mDatabaseManager.mMetadataCache.clear(); 268 // Wait for clear database 269 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 270 } 271 272 @Test testRemoveUnusedMetadata_WithMultiBondedDevices()273 public void testRemoveUnusedMetadata_WithMultiBondedDevices() { 274 // Insert three devices to database and cache, otherDevice1 and otherDevice2 275 // are in the bonded list 276 277 // Add metadata for TEST_BT_ADDR 278 Metadata testData = new Metadata(TEST_BT_ADDR); 279 testData.setCustomizedMeta(0, TEST_BYTE_ARRAY); 280 mDatabaseManager.mMetadataCache.put(TEST_BT_ADDR, testData); 281 mDatabase.insert(testData); 282 283 // Add metadata for OTHER_BT_ADDR1 284 Metadata otherData1 = new Metadata(OTHER_BT_ADDR1); 285 otherData1.setCustomizedMeta(0, TEST_BYTE_ARRAY); 286 mDatabaseManager.mMetadataCache.put(OTHER_BT_ADDR1, otherData1); 287 mDatabase.insert(otherData1); 288 289 // Add metadata for OTHER_BT_ADDR2 290 Metadata otherData2 = new Metadata(OTHER_BT_ADDR2); 291 otherData2.setCustomizedMeta(0, TEST_BYTE_ARRAY); 292 mDatabaseManager.mMetadataCache.put(OTHER_BT_ADDR2, otherData2); 293 mDatabase.insert(otherData2); 294 295 // Add OTHER_BT_ADDR1 OTHER_BT_ADDR2 to bonded devices 296 BluetoothDevice otherDevice1 = BluetoothAdapter.getDefaultAdapter() 297 .getRemoteDevice(OTHER_BT_ADDR1); 298 BluetoothDevice otherDevice2 = BluetoothAdapter.getDefaultAdapter() 299 .getRemoteDevice(OTHER_BT_ADDR2); 300 BluetoothDevice[] bondedDevices = {otherDevice1, otherDevice2}; 301 doReturn(bondedDevices).when(mAdapterService).getBondedDevices(); 302 303 mDatabaseManager.removeUnusedMetadata(); 304 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 305 306 // Check TEST_BT_ADDR report metadata changed to null 307 verify(mAdapterService).metadataChanged(TEST_BT_ADDR, 0, null); 308 309 // Check number of metadata in the database 310 List<Metadata> list = mDatabase.load(); 311 // OTHER_BT_ADDR1 and OTHER_BT_ADDR2 should still in database 312 Assert.assertEquals(2, list.size()); 313 314 // Check whether the devices are in the database 315 Metadata checkData1 = list.get(0); 316 Assert.assertEquals(OTHER_BT_ADDR2, checkData1.getAddress()); 317 Metadata checkData2 = list.get(1); 318 Assert.assertEquals(OTHER_BT_ADDR1, checkData2.getAddress()); 319 320 mDatabaseManager.factoryReset(); 321 mDatabaseManager.mMetadataCache.clear(); 322 // Wait for clear database 323 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 324 325 } 326 327 @Test testSetGetCustomMeta()328 public void testSetGetCustomMeta() { 329 int badKey = 100; 330 byte[] value = "input value".getBytes(); 331 332 // Device is not in database 333 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MANUFACTURER_NAME, 334 value, true); 335 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MODEL_NAME, 336 value, true); 337 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_SOFTWARE_VERSION, 338 value, true); 339 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_HARDWARE_VERSION, 340 value, true); 341 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_COMPANION_APP, 342 value, true); 343 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_ICON, 344 value, true); 345 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET, 346 value, true); 347 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON, 348 value, true); 349 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON, 350 value, true); 351 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_CASE_ICON, 352 value, true); 353 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY, 354 value, true); 355 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY, 356 value, true); 357 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY, 358 value, true); 359 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING, 360 value, true); 361 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING, 362 value, true); 363 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING, 364 value, true); 365 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI, 366 value, true); 367 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_DEVICE_TYPE, 368 value, true); 369 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_BATTERY, 370 value, true); 371 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_CHARGING, 372 value, true); 373 testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD, 374 value, true); 375 testSetGetCustomMetaCase(false, 376 BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD, 377 value, true); 378 testSetGetCustomMetaCase(false, 379 BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD, 380 value, true); 381 testSetGetCustomMetaCase(false, 382 BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD, 383 value, true); 384 testSetGetCustomMetaCase(false, badKey, value, false); 385 386 // Device is in database 387 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MANUFACTURER_NAME, 388 value, true); 389 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MODEL_NAME, 390 value, true); 391 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_SOFTWARE_VERSION, 392 value, true); 393 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_HARDWARE_VERSION, 394 value, true); 395 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_COMPANION_APP, 396 value, true); 397 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_ICON, 398 value, true); 399 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET, 400 value, true); 401 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON, 402 value, true); 403 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON, 404 value, true); 405 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_CASE_ICON, 406 value, true); 407 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY, 408 value, true); 409 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY, 410 value, true); 411 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY, 412 value, true); 413 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING, 414 value, true); 415 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING, 416 value, true); 417 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING, 418 value, true); 419 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI, 420 value, true); 421 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_DEVICE_TYPE, 422 value, true); 423 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_BATTERY, 424 value, true); 425 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_CHARGING, 426 value, true); 427 testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD, 428 value, true); 429 testSetGetCustomMetaCase(true, 430 BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD, 431 value, true); 432 testSetGetCustomMetaCase(true, 433 BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD, 434 value, true); 435 testSetGetCustomMetaCase(true, 436 BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD, 437 value, true); 438 } 439 440 @Test testSetConnection()441 public void testSetConnection() { 442 // Verify pre-conditions to ensure a fresh test 443 Assert.assertEquals(0, mDatabaseManager.mMetadataCache.size()); 444 Assert.assertNotNull(mTestDevice); 445 Assert.assertNotNull(mTestDevice2); 446 Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); 447 448 // Set the first device's connection 449 mDatabaseManager.setConnection(mTestDevice, true); 450 // Wait for database update 451 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 452 Assert.assertTrue(mDatabaseManager 453 .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); 454 List<BluetoothDevice> mostRecentlyConnectedDevicesOrdered = 455 mDatabaseManager.getMostRecentlyConnectedDevices(); 456 Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); 457 Assert.assertEquals(1, mostRecentlyConnectedDevicesOrdered.size()); 458 Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(0)); 459 460 // Setting the second device's connection 461 mDatabaseManager.setConnection(mTestDevice2, true); 462 // Wait for database update 463 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 464 Assert.assertFalse(mDatabaseManager 465 .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); 466 Assert.assertTrue(mDatabaseManager 467 .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); 468 Assert.assertEquals(mTestDevice2, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); 469 mostRecentlyConnectedDevicesOrdered = 470 mDatabaseManager.getMostRecentlyConnectedDevices(); 471 Assert.assertEquals(2, mostRecentlyConnectedDevicesOrdered.size()); 472 Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(0)); 473 Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); 474 475 // Connect first test device again 476 mDatabaseManager.setConnection(mTestDevice, true); 477 // Wait for database update 478 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 479 Assert.assertTrue(mDatabaseManager 480 .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); 481 Assert.assertFalse(mDatabaseManager 482 .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); 483 Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); 484 mostRecentlyConnectedDevicesOrdered = 485 mDatabaseManager.getMostRecentlyConnectedDevices(); 486 Assert.assertEquals(2, mostRecentlyConnectedDevicesOrdered.size()); 487 Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(0)); 488 Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(1)); 489 490 // Disconnect first test device's connection 491 mDatabaseManager.setDisconnection(mTestDevice); 492 // Wait for database update 493 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 494 Assert.assertFalse(mDatabaseManager 495 .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); 496 Assert.assertFalse(mDatabaseManager 497 .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); 498 Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); 499 mostRecentlyConnectedDevicesOrdered = 500 mDatabaseManager.getMostRecentlyConnectedDevices(); 501 Assert.assertEquals(2, mostRecentlyConnectedDevicesOrdered.size()); 502 Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(0)); 503 Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(1)); 504 505 // Connect third test device (non-a2dp device) 506 mDatabaseManager.setConnection(mTestDevice3, false); 507 // Wait for database update 508 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 509 Assert.assertFalse(mDatabaseManager 510 .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); 511 Assert.assertFalse(mDatabaseManager 512 .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); 513 Assert.assertFalse(mDatabaseManager 514 .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); 515 Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); 516 mostRecentlyConnectedDevicesOrdered = 517 mDatabaseManager.getMostRecentlyConnectedDevices(); 518 Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); 519 Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0)); 520 Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); 521 Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2)); 522 523 // Connect first test device again 524 mDatabaseManager.setConnection(mTestDevice, true); 525 // Wait for database update 526 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 527 Assert.assertTrue(mDatabaseManager 528 .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); 529 Assert.assertFalse(mDatabaseManager 530 .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); 531 Assert.assertFalse(mDatabaseManager 532 .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); 533 Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); 534 mostRecentlyConnectedDevicesOrdered = 535 mDatabaseManager.getMostRecentlyConnectedDevices(); 536 Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); 537 Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(0)); 538 Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(1)); 539 Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2)); 540 541 // Connect third test device again and ensure it doesn't reset active a2dp device 542 mDatabaseManager.setConnection(mTestDevice3, false); 543 // Wait for database update 544 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 545 Assert.assertTrue(mDatabaseManager 546 .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); 547 Assert.assertFalse(mDatabaseManager 548 .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); 549 Assert.assertFalse(mDatabaseManager 550 .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); 551 Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); 552 mostRecentlyConnectedDevicesOrdered = 553 mDatabaseManager.getMostRecentlyConnectedDevices(); 554 Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); 555 Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0)); 556 Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); 557 Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2)); 558 559 // Disconnect second test device 560 mDatabaseManager.setDisconnection(mTestDevice2); 561 // Wait for database update 562 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 563 Assert.assertTrue(mDatabaseManager 564 .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); 565 Assert.assertFalse(mDatabaseManager 566 .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); 567 Assert.assertFalse(mDatabaseManager 568 .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); 569 Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); 570 mostRecentlyConnectedDevicesOrdered = 571 mDatabaseManager.getMostRecentlyConnectedDevices(); 572 Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); 573 Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0)); 574 Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); 575 Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2)); 576 577 // Disconnect first test device 578 mDatabaseManager.setDisconnection(mTestDevice); 579 // Wait for database update 580 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 581 Assert.assertFalse(mDatabaseManager 582 .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); 583 Assert.assertFalse(mDatabaseManager 584 .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); 585 Assert.assertFalse(mDatabaseManager 586 .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); 587 Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); 588 mostRecentlyConnectedDevicesOrdered = 589 mDatabaseManager.getMostRecentlyConnectedDevices(); 590 Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); 591 Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0)); 592 Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); 593 Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2)); 594 595 // Disconnect third test device 596 mDatabaseManager.setDisconnection(mTestDevice3); 597 // Wait for database update 598 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 599 Assert.assertFalse(mDatabaseManager 600 .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device); 601 Assert.assertFalse(mDatabaseManager 602 .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device); 603 Assert.assertFalse(mDatabaseManager 604 .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device); 605 Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice()); 606 mostRecentlyConnectedDevicesOrdered = 607 mDatabaseManager.getMostRecentlyConnectedDevices(); 608 Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size()); 609 Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0)); 610 Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1)); 611 Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2)); 612 613 mDatabaseManager.factoryReset(); 614 mDatabaseManager.mMetadataCache.clear(); 615 // Wait for clear database 616 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 617 } 618 619 @Test testDatabaseMigration_100_101()620 public void testDatabaseMigration_100_101() throws IOException { 621 // Create a database with version 100 622 SupportSQLiteDatabase db = testHelper.createDatabase(DB_NAME, 100); 623 Cursor cursor = db.query("SELECT * FROM metadata"); 624 625 // pbap_client_priority should not in version 100 626 assertHasColumn(cursor, "pbap_client_priority", false); 627 628 // Migrate database from 100 to 101 629 db.close(); 630 db = testHelper.runMigrationsAndValidate(DB_NAME, 101, true, 631 MetadataDatabase.MIGRATION_100_101); 632 cursor = db.query("SELECT * FROM metadata"); 633 634 // Check whether pbap_client_priority exists in version 101 635 assertHasColumn(cursor, "pbap_client_priority", true); 636 } 637 638 @Test testDatabaseMigration_101_102()639 public void testDatabaseMigration_101_102() throws IOException { 640 String testString = "TEST STRING"; 641 642 // Create a database with version 101 643 SupportSQLiteDatabase db = testHelper.createDatabase(DB_NAME, 101); 644 Cursor cursor = db.query("SELECT * FROM metadata"); 645 646 // insert a device to the database 647 ContentValues device = new ContentValues(); 648 device.put("address", TEST_BT_ADDR); 649 device.put("migrated", false); 650 device.put("a2dpSupportsOptionalCodecs", -1); 651 device.put("a2dpOptionalCodecsEnabled", -1); 652 device.put("a2dp_priority", -1); 653 device.put("a2dp_sink_priority", -1); 654 device.put("hfp_priority", -1); 655 device.put("hfp_client_priority", -1); 656 device.put("hid_host_priority", -1); 657 device.put("pan_priority", -1); 658 device.put("pbap_priority", -1); 659 device.put("pbap_client_priority", -1); 660 device.put("map_priority", -1); 661 device.put("sap_priority", -1); 662 device.put("hearing_aid_priority", -1); 663 device.put("map_client_priority", -1); 664 device.put("manufacturer_name", testString); 665 device.put("model_name", testString); 666 device.put("software_version", testString); 667 device.put("hardware_version", testString); 668 device.put("companion_app", testString); 669 device.put("main_icon", testString); 670 device.put("is_unthethered_headset", testString); 671 device.put("unthethered_left_icon", testString); 672 device.put("unthethered_right_icon", testString); 673 device.put("unthethered_case_icon", testString); 674 device.put("unthethered_left_battery", testString); 675 device.put("unthethered_right_battery", testString); 676 device.put("unthethered_case_battery", testString); 677 device.put("unthethered_left_charging", testString); 678 device.put("unthethered_right_charging", testString); 679 device.put("unthethered_case_charging", testString); 680 assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), 681 CoreMatchers.not(-1)); 682 683 // Check the metadata names on version 101 684 assertHasColumn(cursor, "is_unthethered_headset", true); 685 assertHasColumn(cursor, "unthethered_left_icon", true); 686 assertHasColumn(cursor, "unthethered_right_icon", true); 687 assertHasColumn(cursor, "unthethered_case_icon", true); 688 assertHasColumn(cursor, "unthethered_left_battery", true); 689 assertHasColumn(cursor, "unthethered_right_battery", true); 690 assertHasColumn(cursor, "unthethered_case_battery", true); 691 assertHasColumn(cursor, "unthethered_left_charging", true); 692 assertHasColumn(cursor, "unthethered_right_charging", true); 693 assertHasColumn(cursor, "unthethered_case_charging", true); 694 695 // Migrate database from 101 to 102 696 db.close(); 697 db = testHelper.runMigrationsAndValidate(DB_NAME, 102, true, 698 MetadataDatabase.MIGRATION_101_102); 699 cursor = db.query("SELECT * FROM metadata"); 700 701 // metadata names should be changed on version 102 702 assertHasColumn(cursor, "is_unthethered_headset", false); 703 assertHasColumn(cursor, "unthethered_left_icon", false); 704 assertHasColumn(cursor, "unthethered_right_icon", false); 705 assertHasColumn(cursor, "unthethered_case_icon", false); 706 assertHasColumn(cursor, "unthethered_left_battery", false); 707 assertHasColumn(cursor, "unthethered_right_battery", false); 708 assertHasColumn(cursor, "unthethered_case_battery", false); 709 assertHasColumn(cursor, "unthethered_left_charging", false); 710 assertHasColumn(cursor, "unthethered_right_charging", false); 711 assertHasColumn(cursor, "unthethered_case_charging", false); 712 713 assertHasColumn(cursor, "is_untethered_headset", true); 714 assertHasColumn(cursor, "untethered_left_icon", true); 715 assertHasColumn(cursor, "untethered_right_icon", true); 716 assertHasColumn(cursor, "untethered_case_icon", true); 717 assertHasColumn(cursor, "untethered_left_battery", true); 718 assertHasColumn(cursor, "untethered_right_battery", true); 719 assertHasColumn(cursor, "untethered_case_battery", true); 720 assertHasColumn(cursor, "untethered_left_charging", true); 721 assertHasColumn(cursor, "untethered_right_charging", true); 722 assertHasColumn(cursor, "untethered_case_charging", true); 723 724 while (cursor.moveToNext()) { 725 // Check whether metadata data type are blob 726 assertColumnBlob(cursor, "manufacturer_name"); 727 assertColumnBlob(cursor, "model_name"); 728 assertColumnBlob(cursor, "software_version"); 729 assertColumnBlob(cursor, "hardware_version"); 730 assertColumnBlob(cursor, "companion_app"); 731 assertColumnBlob(cursor, "main_icon"); 732 assertColumnBlob(cursor, "is_untethered_headset"); 733 assertColumnBlob(cursor, "untethered_left_icon"); 734 assertColumnBlob(cursor, "untethered_right_icon"); 735 assertColumnBlob(cursor, "untethered_case_icon"); 736 assertColumnBlob(cursor, "untethered_left_battery"); 737 assertColumnBlob(cursor, "untethered_right_battery"); 738 assertColumnBlob(cursor, "untethered_case_battery"); 739 assertColumnBlob(cursor, "untethered_left_charging"); 740 assertColumnBlob(cursor, "untethered_right_charging"); 741 assertColumnBlob(cursor, "untethered_case_charging"); 742 743 // Check whether metadata values are migrated to version 102 successfully 744 assertColumnBlobData(cursor, "manufacturer_name", testString.getBytes()); 745 assertColumnBlobData(cursor, "model_name", testString.getBytes()); 746 assertColumnBlobData(cursor, "software_version", testString.getBytes()); 747 assertColumnBlobData(cursor, "hardware_version", testString.getBytes()); 748 assertColumnBlobData(cursor, "companion_app", testString.getBytes()); 749 assertColumnBlobData(cursor, "main_icon", testString.getBytes()); 750 assertColumnBlobData(cursor, "is_untethered_headset", testString.getBytes()); 751 assertColumnBlobData(cursor, "untethered_left_icon", testString.getBytes()); 752 assertColumnBlobData(cursor, "untethered_right_icon", testString.getBytes()); 753 assertColumnBlobData(cursor, "untethered_case_icon", testString.getBytes()); 754 assertColumnBlobData(cursor, "untethered_left_battery", testString.getBytes()); 755 assertColumnBlobData(cursor, "untethered_right_battery", testString.getBytes()); 756 assertColumnBlobData(cursor, "untethered_case_battery", testString.getBytes()); 757 assertColumnBlobData(cursor, "untethered_left_charging", testString.getBytes()); 758 assertColumnBlobData(cursor, "untethered_right_charging", testString.getBytes()); 759 assertColumnBlobData(cursor, "untethered_case_charging", testString.getBytes()); 760 } 761 } 762 763 @Test testDatabaseMigration_102_103()764 public void testDatabaseMigration_102_103() throws IOException { 765 String testString = "TEST STRING"; 766 767 // Create a database with version 102 768 SupportSQLiteDatabase db = testHelper.createDatabase(DB_NAME, 102); 769 Cursor cursor = db.query("SELECT * FROM metadata"); 770 771 // insert a device to the database 772 ContentValues device = new ContentValues(); 773 device.put("address", TEST_BT_ADDR); 774 device.put("migrated", false); 775 device.put("a2dpSupportsOptionalCodecs", -1); 776 device.put("a2dpOptionalCodecsEnabled", -1); 777 device.put("a2dp_priority", 1000); 778 device.put("a2dp_sink_priority", 1000); 779 device.put("hfp_priority", 1000); 780 device.put("hfp_client_priority", 1000); 781 device.put("hid_host_priority", 1000); 782 device.put("pan_priority", 1000); 783 device.put("pbap_priority", 1000); 784 device.put("pbap_client_priority", 1000); 785 device.put("map_priority", 1000); 786 device.put("sap_priority", 1000); 787 device.put("hearing_aid_priority", 1000); 788 device.put("map_client_priority", 1000); 789 device.put("manufacturer_name", testString); 790 device.put("model_name", testString); 791 device.put("software_version", testString); 792 device.put("hardware_version", testString); 793 device.put("companion_app", testString); 794 device.put("main_icon", testString); 795 device.put("is_untethered_headset", testString); 796 device.put("untethered_left_icon", testString); 797 device.put("untethered_right_icon", testString); 798 device.put("untethered_case_icon", testString); 799 device.put("untethered_left_battery", testString); 800 device.put("untethered_right_battery", testString); 801 device.put("untethered_case_battery", testString); 802 device.put("untethered_left_charging", testString); 803 device.put("untethered_right_charging", testString); 804 device.put("untethered_case_charging", testString); 805 assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), 806 CoreMatchers.not(-1)); 807 808 // Check the metadata names on version 102 809 assertHasColumn(cursor, "a2dp_priority", true); 810 assertHasColumn(cursor, "a2dp_sink_priority", true); 811 assertHasColumn(cursor, "hfp_priority", true); 812 assertHasColumn(cursor, "hfp_client_priority", true); 813 assertHasColumn(cursor, "hid_host_priority", true); 814 assertHasColumn(cursor, "pan_priority", true); 815 assertHasColumn(cursor, "pbap_priority", true); 816 assertHasColumn(cursor, "pbap_client_priority", true); 817 assertHasColumn(cursor, "map_priority", true); 818 assertHasColumn(cursor, "sap_priority", true); 819 assertHasColumn(cursor, "hearing_aid_priority", true); 820 assertHasColumn(cursor, "map_client_priority", true); 821 822 // Migrate database from 102 to 103 823 db.close(); 824 db = testHelper.runMigrationsAndValidate(DB_NAME, 103, true, 825 MetadataDatabase.MIGRATION_102_103); 826 cursor = db.query("SELECT * FROM metadata"); 827 828 // metadata names should be changed on version 103 829 assertHasColumn(cursor, "a2dp_priority", false); 830 assertHasColumn(cursor, "a2dp_sink_priority", false); 831 assertHasColumn(cursor, "hfp_priority", false); 832 assertHasColumn(cursor, "hfp_client_priority", false); 833 assertHasColumn(cursor, "hid_host_priority", false); 834 assertHasColumn(cursor, "pan_priority", false); 835 assertHasColumn(cursor, "pbap_priority", false); 836 assertHasColumn(cursor, "pbap_client_priority", false); 837 assertHasColumn(cursor, "map_priority", false); 838 assertHasColumn(cursor, "sap_priority", false); 839 assertHasColumn(cursor, "hearing_aid_priority", false); 840 assertHasColumn(cursor, "map_client_priority", false); 841 842 assertHasColumn(cursor, "a2dp_connection_policy", true); 843 assertHasColumn(cursor, "a2dp_sink_connection_policy", true); 844 assertHasColumn(cursor, "hfp_connection_policy", true); 845 assertHasColumn(cursor, "hfp_client_connection_policy", true); 846 assertHasColumn(cursor, "hid_host_connection_policy", true); 847 assertHasColumn(cursor, "pan_connection_policy", true); 848 assertHasColumn(cursor, "pbap_connection_policy", true); 849 assertHasColumn(cursor, "pbap_client_connection_policy", true); 850 assertHasColumn(cursor, "map_connection_policy", true); 851 assertHasColumn(cursor, "sap_connection_policy", true); 852 assertHasColumn(cursor, "hearing_aid_connection_policy", true); 853 assertHasColumn(cursor, "map_client_connection_policy", true); 854 855 while (cursor.moveToNext()) { 856 // Check PRIORITY_AUTO_CONNECT (1000) was replaced with CONNECTION_POLICY_ALLOWED (100) 857 assertColumnIntData(cursor, "a2dp_connection_policy", 100); 858 assertColumnIntData(cursor, "a2dp_sink_connection_policy", 100); 859 assertColumnIntData(cursor, "hfp_connection_policy", 100); 860 assertColumnIntData(cursor, "hfp_client_connection_policy", 100); 861 assertColumnIntData(cursor, "hid_host_connection_policy", 100); 862 assertColumnIntData(cursor, "pan_connection_policy", 100); 863 assertColumnIntData(cursor, "pbap_connection_policy", 100); 864 assertColumnIntData(cursor, "pbap_client_connection_policy", 100); 865 assertColumnIntData(cursor, "map_connection_policy", 100); 866 assertColumnIntData(cursor, "sap_connection_policy", 100); 867 assertColumnIntData(cursor, "hearing_aid_connection_policy", 100); 868 assertColumnIntData(cursor, "map_client_connection_policy", 100); 869 870 // Check whether metadata data type are blob 871 assertColumnBlob(cursor, "manufacturer_name"); 872 assertColumnBlob(cursor, "model_name"); 873 assertColumnBlob(cursor, "software_version"); 874 assertColumnBlob(cursor, "hardware_version"); 875 assertColumnBlob(cursor, "companion_app"); 876 assertColumnBlob(cursor, "main_icon"); 877 assertColumnBlob(cursor, "is_untethered_headset"); 878 assertColumnBlob(cursor, "untethered_left_icon"); 879 assertColumnBlob(cursor, "untethered_right_icon"); 880 assertColumnBlob(cursor, "untethered_case_icon"); 881 assertColumnBlob(cursor, "untethered_left_battery"); 882 assertColumnBlob(cursor, "untethered_right_battery"); 883 assertColumnBlob(cursor, "untethered_case_battery"); 884 assertColumnBlob(cursor, "untethered_left_charging"); 885 assertColumnBlob(cursor, "untethered_right_charging"); 886 assertColumnBlob(cursor, "untethered_case_charging"); 887 888 // Check whether metadata values are migrated to version 103 successfully 889 assertColumnBlobData(cursor, "manufacturer_name", testString.getBytes()); 890 assertColumnBlobData(cursor, "model_name", testString.getBytes()); 891 assertColumnBlobData(cursor, "software_version", testString.getBytes()); 892 assertColumnBlobData(cursor, "hardware_version", testString.getBytes()); 893 assertColumnBlobData(cursor, "companion_app", testString.getBytes()); 894 assertColumnBlobData(cursor, "main_icon", testString.getBytes()); 895 assertColumnBlobData(cursor, "is_untethered_headset", testString.getBytes()); 896 assertColumnBlobData(cursor, "untethered_left_icon", testString.getBytes()); 897 assertColumnBlobData(cursor, "untethered_right_icon", testString.getBytes()); 898 assertColumnBlobData(cursor, "untethered_case_icon", testString.getBytes()); 899 assertColumnBlobData(cursor, "untethered_left_battery", testString.getBytes()); 900 assertColumnBlobData(cursor, "untethered_right_battery", testString.getBytes()); 901 assertColumnBlobData(cursor, "untethered_case_battery", testString.getBytes()); 902 assertColumnBlobData(cursor, "untethered_left_charging", testString.getBytes()); 903 assertColumnBlobData(cursor, "untethered_right_charging", testString.getBytes()); 904 assertColumnBlobData(cursor, "untethered_case_charging", testString.getBytes()); 905 } 906 } 907 908 @Test testDatabaseMigration_103_104()909 public void testDatabaseMigration_103_104() throws IOException { 910 String testString = "TEST STRING"; 911 912 // Create a database with version 103 913 SupportSQLiteDatabase db = testHelper.createDatabase(DB_NAME, 103); 914 915 // insert a device to the database 916 ContentValues device = new ContentValues(); 917 device.put("address", TEST_BT_ADDR); 918 device.put("migrated", false); 919 device.put("a2dpSupportsOptionalCodecs", -1); 920 device.put("a2dpOptionalCodecsEnabled", -1); 921 device.put("a2dp_connection_policy", 100); 922 device.put("a2dp_sink_connection_policy", 100); 923 device.put("hfp_connection_policy", 100); 924 device.put("hfp_client_connection_policy", 100); 925 device.put("hid_host_connection_policy", 100); 926 device.put("pan_connection_policy", 100); 927 device.put("pbap_connection_policy", 100); 928 device.put("pbap_client_connection_policy", 100); 929 device.put("map_connection_policy", 100); 930 device.put("sap_connection_policy", 100); 931 device.put("hearing_aid_connection_policy", 100); 932 device.put("map_client_connection_policy", 100); 933 device.put("manufacturer_name", testString); 934 device.put("model_name", testString); 935 device.put("software_version", testString); 936 device.put("hardware_version", testString); 937 device.put("companion_app", testString); 938 device.put("main_icon", testString); 939 device.put("is_untethered_headset", testString); 940 device.put("untethered_left_icon", testString); 941 device.put("untethered_right_icon", testString); 942 device.put("untethered_case_icon", testString); 943 device.put("untethered_left_battery", testString); 944 device.put("untethered_right_battery", testString); 945 device.put("untethered_case_battery", testString); 946 device.put("untethered_left_charging", testString); 947 device.put("untethered_right_charging", testString); 948 device.put("untethered_case_charging", testString); 949 assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), 950 CoreMatchers.not(-1)); 951 952 // Migrate database from 103 to 104 953 db.close(); 954 db = testHelper.runMigrationsAndValidate(DB_NAME, 104, true, 955 MetadataDatabase.MIGRATION_103_104); 956 Cursor cursor = db.query("SELECT * FROM metadata"); 957 958 assertHasColumn(cursor, "last_active_time", true); 959 assertHasColumn(cursor, "is_active_a2dp_device", true); 960 961 while (cursor.moveToNext()) { 962 // Check the two new columns were added with their default values 963 assertColumnIntData(cursor, "last_active_time", -1); 964 assertColumnIntData(cursor, "is_active_a2dp_device", 0); 965 } 966 } 967 968 @Test testDatabaseMigration_104_105()969 public void testDatabaseMigration_104_105() throws IOException { 970 // Create a database with version 104 971 SupportSQLiteDatabase db = testHelper.createDatabase(DB_NAME, 104); 972 973 // insert a device to the database 974 ContentValues device = new ContentValues(); 975 device.put("address", TEST_BT_ADDR); 976 977 // Migrate database from 104 to 105 978 db.close(); 979 db = testHelper.runMigrationsAndValidate(DB_NAME, 105, true, 980 MetadataDatabase.MIGRATION_104_105); 981 Cursor cursor = db.query("SELECT * FROM metadata"); 982 983 assertHasColumn(cursor, "device_type", true); 984 assertHasColumn(cursor, "main_battery", true); 985 assertHasColumn(cursor, "main_charging", true); 986 assertHasColumn(cursor, "main_low_battery_threshold", true); 987 assertHasColumn(cursor, "untethered_right_low_battery_threshold", true); 988 assertHasColumn(cursor, "untethered_left_low_battery_threshold", true); 989 assertHasColumn(cursor, "untethered_case_low_battery_threshold", true); 990 991 while (cursor.moveToNext()) { 992 // Check the old column have the original value 993 assertColumnBlobData(cursor, "address", TEST_BT_ADDR.getBytes()); 994 995 // Check the new columns were added with their default values 996 assertColumnBlobData(cursor, "device_type", null); 997 assertColumnBlobData(cursor, "main_battery", null); 998 assertColumnBlobData(cursor, "main_charging", null); 999 assertColumnBlobData(cursor, "main_low_battery_threshold", null); 1000 assertColumnBlobData(cursor, "untethered_right_low_battery_threshold", null); 1001 assertColumnBlobData(cursor, "untethered_left_low_battery_threshold", null); 1002 assertColumnBlobData(cursor, "untethered_case_low_battery_threshold", null); 1003 } 1004 } 1005 1006 @Test testDatabaseMigration_105_106()1007 public void testDatabaseMigration_105_106() throws IOException { 1008 String testString = "TEST STRING"; 1009 1010 // Create a database with version 105 1011 SupportSQLiteDatabase db = testHelper.createDatabase(DB_NAME, 105); 1012 1013 // insert a device to the database 1014 ContentValues device = new ContentValues(); 1015 device.put("address", TEST_BT_ADDR); 1016 device.put("migrated", false); 1017 assertThat(db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), 1018 CoreMatchers.not(-1)); 1019 1020 // Migrate database from 105 to 106 1021 db.close(); 1022 db = testHelper.runMigrationsAndValidate(DB_NAME, 106, true, 1023 MetadataDatabase.MIGRATION_105_106); 1024 Cursor cursor = db.query("SELECT * FROM metadata"); 1025 1026 assertHasColumn(cursor, "le_audio_connection_policy", true); 1027 1028 while (cursor.moveToNext()) { 1029 // Check the new columns was added with default value 1030 assertColumnIntData(cursor, "le_audio_connection_policy", 100); 1031 } 1032 } 1033 1034 /** 1035 * Helper function to check whether the database has the expected column 1036 */ assertHasColumn(Cursor cursor, String columnName, boolean hasColumn)1037 void assertHasColumn(Cursor cursor, String columnName, boolean hasColumn) { 1038 if (hasColumn) { 1039 assertThat(cursor.getColumnIndex(columnName), CoreMatchers.not(-1)); 1040 } else { 1041 assertThat(cursor.getColumnIndex(columnName), CoreMatchers.is(-1)); 1042 } 1043 } 1044 1045 /** 1046 * Helper function to check whether the database has the expected value 1047 */ assertColumnIntData(Cursor cursor, String columnName, int value)1048 void assertColumnIntData(Cursor cursor, String columnName, int value) { 1049 assertThat(cursor.getInt(cursor.getColumnIndex(columnName)), CoreMatchers.is(value)); 1050 } 1051 1052 /** 1053 * Helper function to check whether the column data type is BLOB 1054 */ assertColumnBlob(Cursor cursor, String columnName)1055 void assertColumnBlob(Cursor cursor, String columnName) { 1056 assertThat(cursor.getType(cursor.getColumnIndex(columnName)), 1057 CoreMatchers.is(Cursor.FIELD_TYPE_BLOB)); 1058 } 1059 1060 /** 1061 * Helper function to check the BLOB data in a column is expected 1062 */ assertColumnBlobData(Cursor cursor, String columnName, byte[] data)1063 void assertColumnBlobData(Cursor cursor, String columnName, byte[] data) { 1064 assertThat(cursor.getBlob(cursor.getColumnIndex(columnName)), 1065 CoreMatchers.is(data)); 1066 } 1067 restartDatabaseManagerHelper()1068 void restartDatabaseManagerHelper() { 1069 Metadata data = new Metadata(LOCAL_STORAGE); 1070 data.migrated = true; 1071 mDatabase.insert(data); 1072 1073 mDatabaseManager.cleanup(); 1074 mDatabaseManager.start(mDatabase); 1075 // Wait for handler thread finish its task. 1076 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 1077 1078 // Remove local storage 1079 mDatabaseManager.mMetadataCache.remove(LOCAL_STORAGE); 1080 mDatabaseManager.deleteDatabase(data); 1081 // Wait for handler thread finish its task. 1082 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 1083 } 1084 testSetGetProfileConnectionPolicyCase(boolean stored, int connectionPolicy, int expectedConnectionPolicy, boolean expectedSetResult)1085 void testSetGetProfileConnectionPolicyCase(boolean stored, int connectionPolicy, 1086 int expectedConnectionPolicy, boolean expectedSetResult) { 1087 if (stored) { 1088 Metadata data = new Metadata(TEST_BT_ADDR); 1089 mDatabaseManager.mMetadataCache.put(TEST_BT_ADDR, data); 1090 mDatabase.insert(data); 1091 } 1092 Assert.assertEquals(expectedSetResult, 1093 mDatabaseManager.setProfileConnectionPolicy(mTestDevice, 1094 BluetoothProfile.HEADSET, connectionPolicy)); 1095 Assert.assertEquals(expectedConnectionPolicy, 1096 mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.HEADSET)); 1097 // Wait for database update 1098 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 1099 1100 List<Metadata> list = mDatabase.load(); 1101 1102 // Check number of metadata in the database 1103 if (!stored) { 1104 if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN 1105 && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) { 1106 // Database won't be updated 1107 Assert.assertEquals(0, list.size()); 1108 return; 1109 } 1110 } 1111 Assert.assertEquals(1, list.size()); 1112 1113 // Check whether the device is in database 1114 restartDatabaseManagerHelper(); 1115 Assert.assertEquals(expectedConnectionPolicy, 1116 mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.HEADSET)); 1117 1118 mDatabaseManager.factoryReset(); 1119 mDatabaseManager.mMetadataCache.clear(); 1120 // Wait for clear database 1121 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 1122 } 1123 testSetGetA2dpOptionalCodecsCase(int test, boolean stored, int value, int expectedValue)1124 void testSetGetA2dpOptionalCodecsCase(int test, boolean stored, int value, int expectedValue) { 1125 if (stored) { 1126 Metadata data = new Metadata(TEST_BT_ADDR); 1127 mDatabaseManager.mMetadataCache.put(TEST_BT_ADDR, data); 1128 mDatabase.insert(data); 1129 } 1130 if (test == A2DP_SUPPORT_OP_CODEC_TEST) { 1131 mDatabaseManager.setA2dpSupportsOptionalCodecs(mTestDevice, value); 1132 Assert.assertEquals(expectedValue, 1133 mDatabaseManager.getA2dpSupportsOptionalCodecs(mTestDevice)); 1134 } else { 1135 mDatabaseManager.setA2dpOptionalCodecsEnabled(mTestDevice, value); 1136 Assert.assertEquals(expectedValue, 1137 mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice)); 1138 } 1139 // Wait for database update 1140 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 1141 1142 List<Metadata> list = mDatabase.load(); 1143 1144 // Check number of metadata in the database 1145 if (!stored) { 1146 // Database won't be updated 1147 Assert.assertEquals(0, list.size()); 1148 return; 1149 } 1150 Assert.assertEquals(1, list.size()); 1151 1152 // Check whether the device is in database 1153 restartDatabaseManagerHelper(); 1154 if (test == A2DP_SUPPORT_OP_CODEC_TEST) { 1155 Assert.assertEquals(expectedValue, 1156 mDatabaseManager.getA2dpSupportsOptionalCodecs(mTestDevice)); 1157 } else { 1158 Assert.assertEquals(expectedValue, 1159 mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice)); 1160 } 1161 1162 mDatabaseManager.factoryReset(); 1163 mDatabaseManager.mMetadataCache.clear(); 1164 // Wait for clear database 1165 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 1166 } 1167 testSetGetCustomMetaCase(boolean stored, int key, byte[] value, boolean expectedResult)1168 void testSetGetCustomMetaCase(boolean stored, int key, byte[] value, boolean expectedResult) { 1169 byte[] testValue = "test value".getBytes(); 1170 int verifyTime = 1; 1171 if (stored) { 1172 Metadata data = new Metadata(TEST_BT_ADDR); 1173 mDatabaseManager.mMetadataCache.put(TEST_BT_ADDR, data); 1174 mDatabase.insert(data); 1175 Assert.assertEquals(expectedResult, 1176 mDatabaseManager.setCustomMeta(mTestDevice, key, testValue)); 1177 verify(mAdapterService).metadataChanged(TEST_BT_ADDR, key, testValue); 1178 verifyTime++; 1179 } 1180 Assert.assertEquals(expectedResult, 1181 mDatabaseManager.setCustomMeta(mTestDevice, key, value)); 1182 if (expectedResult) { 1183 // Check for callback and get value 1184 verify(mAdapterService, times(verifyTime)).metadataChanged(TEST_BT_ADDR, key, value); 1185 Assert.assertEquals(value, 1186 mDatabaseManager.getCustomMeta(mTestDevice, key)); 1187 } else { 1188 Assert.assertNull(mDatabaseManager.getCustomMeta(mTestDevice, key)); 1189 return; 1190 } 1191 // Wait for database update 1192 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 1193 1194 // Check whether the value is saved in database 1195 restartDatabaseManagerHelper(); 1196 Assert.assertArrayEquals(value, 1197 mDatabaseManager.getCustomMeta(mTestDevice, key)); 1198 1199 mDatabaseManager.factoryReset(); 1200 mDatabaseManager.mMetadataCache.clear(); 1201 // Wait for clear database 1202 TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper()); 1203 } 1204 } 1205