Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb943370 authored by Srinivas Patibandla's avatar Srinivas Patibandla
Browse files

Define METADATA_EXCLUSIVE_MANAGER to set the exclusive manager app for the BluetoothDevice

Bug: 280805266
Bug: 319716512
Test: atest com.android.bluetooth.btservice.storage.DatabaseManagerTest
Change-Id: I6b7c3c690a43401659c9ee555d2afc6e97b76ba0
parent d4bb3fa3
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ class CustomizedMetadataEntity {
    public byte[] le_audio;
    public byte[] gmcs_cccd;
    public byte[] gtbs_cccd;
    public byte[] exclusive_manager;

    public String toString() {
        StringBuilder builder = new StringBuilder();
@@ -109,8 +110,9 @@ class CustomizedMetadataEntity {
                .append("|gmcs_cccd=")
                .append(metadataToString(gmcs_cccd))
                .append("|gtbs_cccd=")
                .append(metadataToString(gtbs_cccd));

                .append(metadataToString(gtbs_cccd))
                .append("|exclusive_manager=")
                .append(metadataToString(exclusive_manager));

        return builder.toString();
    }
+6 −0
Original line number Diff line number Diff line
@@ -349,6 +349,9 @@ public class Metadata {
            case BluetoothDevice.METADATA_GTBS_CCCD:
                publicMetadata.gtbs_cccd = value;
                break;
            case BluetoothDevice.METADATA_EXCLUSIVE_MANAGER:
                publicMetadata.exclusive_manager = value;
                break;
        }
    }

@@ -446,6 +449,9 @@ public class Metadata {
            case BluetoothDevice.METADATA_GTBS_CCCD:
                value = publicMetadata.gtbs_cccd;
                break;
            case BluetoothDevice.METADATA_EXCLUSIVE_MANAGER:
                value = publicMetadata.exclusive_manager;
                break;
        }
        return value;
    }
+20 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ import java.util.List;
/** MetadataDatabase is a Room database stores Bluetooth persistence data */
@Database(
        entities = {Metadata.class},
        version = 118)
        version = 119)
public abstract class MetadataDatabase extends RoomDatabase {
    /** The metadata database file name */
    public static final String DATABASE_NAME = "bluetooth_db";
@@ -68,6 +68,7 @@ public abstract class MetadataDatabase extends RoomDatabase {
                .addMigrations(MIGRATION_115_116)
                .addMigrations(MIGRATION_116_117)
                .addMigrations(MIGRATION_117_118)
                .addMigrations(MIGRATION_118_119)
                .allowMainThreadQueries()
                .build();
    }
@@ -630,4 +631,22 @@ public abstract class MetadataDatabase extends RoomDatabase {
                    }
                }
            };

    @VisibleForTesting
    static final Migration MIGRATION_118_119 =
            new Migration(118, 119) {
                @Override
                public void migrate(SupportSQLiteDatabase database) {
                    try {
                        database.execSQL(
                                "ALTER TABLE metadata ADD COLUMN `exclusive_manager` BLOB");
                    } catch (SQLException ex) {
                        // Check if user has new schema, but is just missing the version update
                        Cursor cursor = database.query("SELECT * FROM metadata");
                        if (cursor == null || cursor.getColumnIndex("exclusive_manager") == -1) {
                            throw ex;
                        }
                    }
                }
            };
}
+27 −0
Original line number Diff line number Diff line
@@ -408,6 +408,7 @@ public final class DatabaseManagerTest {
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_GTBS_CCCD,
                value, true);
        testSetGetCustomMetaCase(false, badKey, value, false);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_EXCLUSIVE_MANAGER, value, true);

        // Device is in database
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MANUFACTURER_NAME,
@@ -471,6 +472,7 @@ public final class DatabaseManagerTest {
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_GTBS_CCCD,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_EXCLUSIVE_MANAGER, value, true);
    }
    @Test
    public void testSetGetAudioPolicyMetaData() {
@@ -1427,6 +1429,31 @@ public final class DatabaseManagerTest {
        }
    }

    @Test
    public void testDatabaseMigration_118_119() throws IOException {
        // Create a database with version 118
        SupportSQLiteDatabase db = testHelper.createDatabase(DB_NAME, 118);
        // insert a device to the database
        ContentValues device = new ContentValues();
        device.put("address", TEST_BT_ADDR);
        device.put("migrated", false);
        assertThat(
                db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device),
                CoreMatchers.not(-1));

        // Migrate database from 118 to 119
        db.close();
        db =
                testHelper.runMigrationsAndValidate(
                        DB_NAME, 119, true, MetadataDatabase.MIGRATION_118_119);
        Cursor cursor = db.query("SELECT * FROM metadata");
        assertHasColumn(cursor, "exclusive_manager", true);
        while (cursor.moveToNext()) {
            // Check the new column was added with default value
            assertColumnBlobData(cursor, "exclusive_manager", null);
        }
    }

    /**
     * Helper function to check whether the database has the expected column
     */
+394 −0
Original line number Diff line number Diff line
{
  "formatVersion": 1,
  "database": {
    "version": 119,
    "identityHash": "7f463dc18499d33a731e823f5d522892",
    "entities": [
      {
        "tableName": "metadata",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`address` TEXT NOT NULL, `migrated` INTEGER NOT NULL, `a2dpSupportsOptionalCodecs` INTEGER NOT NULL, `a2dpOptionalCodecsEnabled` INTEGER NOT NULL, `last_active_time` INTEGER NOT NULL, `is_active_a2dp_device` INTEGER NOT NULL, `isActiveHfpDevice` INTEGER NOT NULL, `preferred_output_only_profile` INTEGER NOT NULL, `preferred_duplex_profile` INTEGER NOT NULL, `a2dp_connection_policy` INTEGER, `a2dp_sink_connection_policy` INTEGER, `hfp_connection_policy` INTEGER, `hfp_client_connection_policy` INTEGER, `hid_host_connection_policy` INTEGER, `pan_connection_policy` INTEGER, `pbap_connection_policy` INTEGER, `pbap_client_connection_policy` INTEGER, `map_connection_policy` INTEGER, `sap_connection_policy` INTEGER, `hearing_aid_connection_policy` INTEGER, `hap_client_connection_policy` INTEGER, `map_client_connection_policy` INTEGER, `le_audio_connection_policy` INTEGER, `volume_control_connection_policy` INTEGER, `csip_set_coordinator_connection_policy` INTEGER, `le_call_control_connection_policy` INTEGER, `bass_client_connection_policy` INTEGER, `battery_connection_policy` INTEGER, `manufacturer_name` BLOB, `model_name` BLOB, `software_version` BLOB, `hardware_version` BLOB, `companion_app` BLOB, `main_icon` BLOB, `is_untethered_headset` BLOB, `untethered_left_icon` BLOB, `untethered_right_icon` BLOB, `untethered_case_icon` BLOB, `untethered_left_battery` BLOB, `untethered_right_battery` BLOB, `untethered_case_battery` BLOB, `untethered_left_charging` BLOB, `untethered_right_charging` BLOB, `untethered_case_charging` BLOB, `enhanced_settings_ui_uri` BLOB, `device_type` BLOB, `main_battery` BLOB, `main_charging` BLOB, `main_low_battery_threshold` BLOB, `untethered_left_low_battery_threshold` BLOB, `untethered_right_low_battery_threshold` BLOB, `untethered_case_low_battery_threshold` BLOB, `spatial_audio` BLOB, `fastpair_customized` BLOB, `le_audio` BLOB, `gmcs_cccd` BLOB, `gtbs_cccd` BLOB, `exclusive_manager` BLOB, `call_establish_audio_policy` INTEGER, `connecting_time_audio_policy` INTEGER, `in_band_ringtone_audio_policy` INTEGER, PRIMARY KEY(`address`))",
        "fields": [
          {
            "fieldPath": "address",
            "columnName": "address",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "migrated",
            "columnName": "migrated",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "a2dpSupportsOptionalCodecs",
            "columnName": "a2dpSupportsOptionalCodecs",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "a2dpOptionalCodecsEnabled",
            "columnName": "a2dpOptionalCodecsEnabled",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "last_active_time",
            "columnName": "last_active_time",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "is_active_a2dp_device",
            "columnName": "is_active_a2dp_device",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "isActiveHfpDevice",
            "columnName": "isActiveHfpDevice",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "preferred_output_only_profile",
            "columnName": "preferred_output_only_profile",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "preferred_duplex_profile",
            "columnName": "preferred_duplex_profile",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "profileConnectionPolicies.a2dp_connection_policy",
            "columnName": "a2dp_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.a2dp_sink_connection_policy",
            "columnName": "a2dp_sink_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.hfp_connection_policy",
            "columnName": "hfp_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.hfp_client_connection_policy",
            "columnName": "hfp_client_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.hid_host_connection_policy",
            "columnName": "hid_host_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.pan_connection_policy",
            "columnName": "pan_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.pbap_connection_policy",
            "columnName": "pbap_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.pbap_client_connection_policy",
            "columnName": "pbap_client_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.map_connection_policy",
            "columnName": "map_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.sap_connection_policy",
            "columnName": "sap_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.hearing_aid_connection_policy",
            "columnName": "hearing_aid_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.hap_client_connection_policy",
            "columnName": "hap_client_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.map_client_connection_policy",
            "columnName": "map_client_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.le_audio_connection_policy",
            "columnName": "le_audio_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.volume_control_connection_policy",
            "columnName": "volume_control_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.csip_set_coordinator_connection_policy",
            "columnName": "csip_set_coordinator_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.le_call_control_connection_policy",
            "columnName": "le_call_control_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.bass_client_connection_policy",
            "columnName": "bass_client_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "profileConnectionPolicies.battery_connection_policy",
            "columnName": "battery_connection_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.manufacturer_name",
            "columnName": "manufacturer_name",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.model_name",
            "columnName": "model_name",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.software_version",
            "columnName": "software_version",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.hardware_version",
            "columnName": "hardware_version",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.companion_app",
            "columnName": "companion_app",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.main_icon",
            "columnName": "main_icon",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.is_untethered_headset",
            "columnName": "is_untethered_headset",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_left_icon",
            "columnName": "untethered_left_icon",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_right_icon",
            "columnName": "untethered_right_icon",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_case_icon",
            "columnName": "untethered_case_icon",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_left_battery",
            "columnName": "untethered_left_battery",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_right_battery",
            "columnName": "untethered_right_battery",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_case_battery",
            "columnName": "untethered_case_battery",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_left_charging",
            "columnName": "untethered_left_charging",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_right_charging",
            "columnName": "untethered_right_charging",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_case_charging",
            "columnName": "untethered_case_charging",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.enhanced_settings_ui_uri",
            "columnName": "enhanced_settings_ui_uri",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.device_type",
            "columnName": "device_type",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.main_battery",
            "columnName": "main_battery",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.main_charging",
            "columnName": "main_charging",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.main_low_battery_threshold",
            "columnName": "main_low_battery_threshold",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_left_low_battery_threshold",
            "columnName": "untethered_left_low_battery_threshold",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_right_low_battery_threshold",
            "columnName": "untethered_right_low_battery_threshold",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.untethered_case_low_battery_threshold",
            "columnName": "untethered_case_low_battery_threshold",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.spatial_audio",
            "columnName": "spatial_audio",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.fastpair_customized",
            "columnName": "fastpair_customized",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.le_audio",
            "columnName": "le_audio",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.gmcs_cccd",
            "columnName": "gmcs_cccd",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.gtbs_cccd",
            "columnName": "gtbs_cccd",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "publicMetadata.exclusive_manager",
            "columnName": "exclusive_manager",
            "affinity": "BLOB",
            "notNull": false
          },
          {
            "fieldPath": "audioPolicyMetadata.callEstablishAudioPolicy",
            "columnName": "call_establish_audio_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "audioPolicyMetadata.connectingTimeAudioPolicy",
            "columnName": "connecting_time_audio_policy",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "audioPolicyMetadata.inBandRingtoneAudioPolicy",
            "columnName": "in_band_ringtone_audio_policy",
            "affinity": "INTEGER",
            "notNull": false
          }
        ],
        "primaryKey": {
          "autoGenerate": false,
          "columnNames": [
            "address"
          ]
        },
        "indices": [],
        "foreignKeys": []
      }
    ],
    "views": [],
    "setupQueries": [
      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7f463dc18499d33a731e823f5d522892')"
    ]
  }
}
 No newline at end of file
Loading