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

Commit d468cedb authored by Jakub Pawłowski's avatar Jakub Pawłowski Committed by Gerrit Code Review
Browse files

Merge "mcp: Fix non-deterministic order of GATT attributes"

parents e1a823ea faeca903
Loading
Loading
Loading
Loading
+117 −134
Original line number Original line Diff line number Diff line
@@ -41,6 +41,7 @@ import android.content.Context;
import android.os.Handler;
import android.os.Handler;
import android.os.Looper;
import android.os.Looper;
import android.util.Log;
import android.util.Log;
import android.util.Pair;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;


@@ -919,10 +920,9 @@ public class MediaControlGattService implements MediaControlGattServiceInterface
        mGattService =
        mGattService =
                new BluetoothGattService(serviceUuid, BluetoothGattService.SERVICE_TYPE_PRIMARY);
                new BluetoothGattService(serviceUuid, BluetoothGattService.SERVICE_TYPE_PRIMARY);


        for (Map.Entry<UUID, CharacteristicData> entry :
        for (Pair<UUID, CharacteristicData> entry : getUuidCharacteristicList()) {
                sUuidToCharacteristic.entrySet()) {
            CharacteristicData desc = entry.second;
            CharacteristicData desc = entry.getValue();
            UUID uuid = entry.first;
            UUID uuid = entry.getKey();
            if (VDBG) {
            if (VDBG) {
                Log.d(TAG, "Checking uuid: " + uuid);
                Log.d(TAG, "Checking uuid: " + uuid);
            }
            }
@@ -1702,136 +1702,119 @@ public class MediaControlGattService implements MediaControlGattServiceInterface
    /* All characteristic attributes (UUIDs, properties, permissions and flags needed to enable
    /* All characteristic attributes (UUIDs, properties, permissions and flags needed to enable
     * them) This is set according to the Media Control Service Specification.
     * them) This is set according to the Media Control Service Specification.
     */
     */
    private final static Map<UUID, CharacteristicData> sUuidToCharacteristic = Map.ofEntries(
    private static List<Pair<UUID, CharacteristicData>> getUuidCharacteristicList() {
            entry(UUID_PLAYER_NAME,
        List<Pair<UUID, CharacteristicData>> characteristics = new ArrayList<>();
                    new CharacteristicData(CharId.PLAYER_NAME,
        characteristics.add(new Pair<>(UUID_PLAYER_NAME,
                            ServiceFeature.PLAYER_NAME, ServiceFeature.PLAYER_NAME_NOTIFY,
                new CharacteristicData(CharId.PLAYER_NAME, ServiceFeature.PLAYER_NAME,
                            PROPERTY_READ,
                        ServiceFeature.PLAYER_NAME_NOTIFY, PROPERTY_READ,
                            PERMISSION_READ_ENCRYPTED)),
                        PERMISSION_READ_ENCRYPTED)));
            entry(UUID_PLAYER_ICON_OBJ_ID,
        characteristics.add(new Pair<>(UUID_PLAYER_ICON_OBJ_ID,
                    new CharacteristicData(CharId.PLAYER_ICON_OBJ_ID,
                new CharacteristicData(CharId.PLAYER_ICON_OBJ_ID, ServiceFeature.PLAYER_ICON_OBJ_ID,
                            ServiceFeature.PLAYER_ICON_OBJ_ID,
                        // Notifications unsupported
                        // Notifications unsupported
                            0, PROPERTY_READ,
                        0, PROPERTY_READ, PERMISSION_READ_ENCRYPTED)));
                            PERMISSION_READ_ENCRYPTED)),
        characteristics.add(new Pair<>(UUID_PLAYER_ICON_URL,
            entry(UUID_PLAYER_ICON_URL,
                new CharacteristicData(CharId.PLAYER_ICON_URL, ServiceFeature.PLAYER_ICON_URL,
                    new CharacteristicData(CharId.PLAYER_ICON_URL,
                            ServiceFeature.PLAYER_ICON_URL,
                        // Notifications unsupported
                        // Notifications unsupported
                            0, PROPERTY_READ,
                        0, PROPERTY_READ, PERMISSION_READ_ENCRYPTED)));
                            PERMISSION_READ_ENCRYPTED)),
        characteristics.add(new Pair<>(UUID_TRACK_CHANGED,
            entry(UUID_TRACK_CHANGED,
                new CharacteristicData(CharId.TRACK_CHANGED, ServiceFeature.TRACK_CHANGED,
                    new CharacteristicData(CharId.TRACK_CHANGED,
                            ServiceFeature.TRACK_CHANGED,
                        // Mandatory notification if char. exists.
                        // Mandatory notification if char. exists.
                            ServiceFeature.TRACK_CHANGED,
                        ServiceFeature.TRACK_CHANGED, PROPERTY_NOTIFY, 0)));
                            PROPERTY_NOTIFY, 0)),
        characteristics.add(new Pair<>(UUID_TRACK_TITLE,
            entry(UUID_TRACK_TITLE,
                new CharacteristicData(CharId.TRACK_TITLE, ServiceFeature.TRACK_TITLE,
                    new CharacteristicData(CharId.TRACK_TITLE,
                        ServiceFeature.TRACK_TITLE_NOTIFY, PROPERTY_READ,
                            ServiceFeature.TRACK_TITLE, ServiceFeature.TRACK_TITLE_NOTIFY,
                        PERMISSION_READ_ENCRYPTED)));
                            PROPERTY_READ,
        characteristics.add(new Pair<>(UUID_TRACK_DURATION,
                            PERMISSION_READ_ENCRYPTED)),
                new CharacteristicData(CharId.TRACK_DURATION, ServiceFeature.TRACK_DURATION,
            entry(UUID_TRACK_DURATION,
                        ServiceFeature.TRACK_DURATION_NOTIFY, PROPERTY_READ,
                    new CharacteristicData(CharId.TRACK_DURATION,
                        PERMISSION_READ_ENCRYPTED)));
                            ServiceFeature.TRACK_DURATION, ServiceFeature.TRACK_DURATION_NOTIFY,
        characteristics.add(new Pair<>(UUID_TRACK_POSITION,
                            PROPERTY_READ,
                new CharacteristicData(CharId.TRACK_POSITION, ServiceFeature.TRACK_POSITION,
                            PERMISSION_READ_ENCRYPTED)),
                        ServiceFeature.TRACK_POSITION_NOTIFY,
            entry(UUID_TRACK_POSITION,
                    new CharacteristicData(CharId.TRACK_POSITION,
                            ServiceFeature.TRACK_POSITION, ServiceFeature.TRACK_POSITION_NOTIFY,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                            PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)),
                        PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)));
            entry(UUID_PLAYBACK_SPEED,
        characteristics.add(new Pair<>(UUID_PLAYBACK_SPEED,
                    new CharacteristicData(CharId.PLAYBACK_SPEED,
                new CharacteristicData(CharId.PLAYBACK_SPEED, ServiceFeature.PLAYBACK_SPEED,
                            ServiceFeature.PLAYBACK_SPEED, ServiceFeature.PLAYBACK_SPEED_NOTIFY,
                        ServiceFeature.PLAYBACK_SPEED_NOTIFY,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                            PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)),
                        PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)));
            entry(UUID_SEEKING_SPEED,
        characteristics.add(new Pair<>(UUID_SEEKING_SPEED,
                    new CharacteristicData(CharId.SEEKING_SPEED,
                new CharacteristicData(CharId.SEEKING_SPEED, ServiceFeature.SEEKING_SPEED,
                            ServiceFeature.SEEKING_SPEED, ServiceFeature.SEEKING_SPEED_NOTIFY,
                        ServiceFeature.SEEKING_SPEED_NOTIFY, PROPERTY_READ,
                            PROPERTY_READ,
                        PERMISSION_READ_ENCRYPTED)));
                            PERMISSION_READ_ENCRYPTED)),
        characteristics.add(new Pair<>(UUID_CURRENT_TRACK_SEGMENT_OBJ_ID,
            entry(UUID_CURRENT_TRACK_SEGMENT_OBJ_ID,
                new CharacteristicData(CharId.CURRENT_TRACK_SEGMENT_OBJ_ID,
                new CharacteristicData(CharId.CURRENT_TRACK_SEGMENT_OBJ_ID,
                        ServiceFeature.CURRENT_TRACK_SEGMENT_OBJ_ID,
                        ServiceFeature.CURRENT_TRACK_SEGMENT_OBJ_ID,
                        // Notifications unsupported
                        // Notifications unsupported
                            0, PROPERTY_READ,
                        0, PROPERTY_READ, PERMISSION_READ_ENCRYPTED)));
                            PERMISSION_READ_ENCRYPTED)),
        characteristics.add(new Pair<>(UUID_CURRENT_TRACK_OBJ_ID,
            entry(UUID_CURRENT_TRACK_OBJ_ID,
                new CharacteristicData(CharId.CURRENT_TRACK_OBJ_ID,
                new CharacteristicData(CharId.CURRENT_TRACK_OBJ_ID,
                        ServiceFeature.CURRENT_TRACK_OBJ_ID,
                        ServiceFeature.CURRENT_TRACK_OBJ_ID,
                        ServiceFeature.CURRENT_TRACK_OBJ_ID_NOTIFY,
                        ServiceFeature.CURRENT_TRACK_OBJ_ID_NOTIFY,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                            PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)),
                        PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)));
            entry(UUID_NEXT_TRACK_OBJ_ID,
        characteristics.add(new Pair<>(UUID_NEXT_TRACK_OBJ_ID,
                    new CharacteristicData(CharId.NEXT_TRACK_OBJ_ID,
                new CharacteristicData(CharId.NEXT_TRACK_OBJ_ID, ServiceFeature.NEXT_TRACK_OBJ_ID,
                            ServiceFeature.NEXT_TRACK_OBJ_ID,
                        ServiceFeature.NEXT_TRACK_OBJ_ID_NOTIFY,
                        ServiceFeature.NEXT_TRACK_OBJ_ID_NOTIFY,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                            PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)),
                        PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)));
            entry(UUID_CURRENT_GROUP_OBJ_ID,
        characteristics.add(new Pair<>(UUID_CURRENT_GROUP_OBJ_ID,
                new CharacteristicData(CharId.CURRENT_GROUP_OBJ_ID,
                new CharacteristicData(CharId.CURRENT_GROUP_OBJ_ID,
                        ServiceFeature.CURRENT_GROUP_OBJ_ID,
                        ServiceFeature.CURRENT_GROUP_OBJ_ID,
                        ServiceFeature.CURRENT_GROUP_OBJ_ID_NOTIFY,
                        ServiceFeature.CURRENT_GROUP_OBJ_ID_NOTIFY,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                            PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)),
                        PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)));
            entry(UUID_PARENT_GROUP_OBJ_ID,
        characteristics.add(new Pair<>(UUID_PARENT_GROUP_OBJ_ID,
                new CharacteristicData(CharId.PARENT_GROUP_OBJ_ID,
                new CharacteristicData(CharId.PARENT_GROUP_OBJ_ID,
                        ServiceFeature.PARENT_GROUP_OBJ_ID,
                        ServiceFeature.PARENT_GROUP_OBJ_ID,
                            ServiceFeature.PARENT_GROUP_OBJ_ID_NOTIFY,
                        ServiceFeature.PARENT_GROUP_OBJ_ID_NOTIFY, PROPERTY_READ,
                            PROPERTY_READ,
                        PERMISSION_READ_ENCRYPTED)));
                            PERMISSION_READ_ENCRYPTED)),
        characteristics.add(new Pair<>(UUID_PLAYING_ORDER,
            entry(UUID_PLAYING_ORDER,
                new CharacteristicData(CharId.PLAYING_ORDER, ServiceFeature.PLAYING_ORDER,
                    new CharacteristicData(CharId.PLAYING_ORDER,
                        ServiceFeature.PLAYING_ORDER_NOTIFY,
                            ServiceFeature.PLAYING_ORDER, ServiceFeature.PLAYING_ORDER_NOTIFY,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                        PROPERTY_READ | PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE,
                            PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)),
                        PERMISSION_READ_ENCRYPTED | PERMISSION_WRITE_ENCRYPTED)));
            entry(UUID_PLAYING_ORDER_SUPPORTED,
        characteristics.add(new Pair<>(UUID_PLAYING_ORDER_SUPPORTED,
                new CharacteristicData(CharId.PLAYING_ORDER_SUPPORTED,
                new CharacteristicData(CharId.PLAYING_ORDER_SUPPORTED,
                        ServiceFeature.PLAYING_ORDER_SUPPORTED,
                        ServiceFeature.PLAYING_ORDER_SUPPORTED,
                        // Notifications unsupported
                        // Notifications unsupported
                            0, PROPERTY_READ,
                        0, PROPERTY_READ, PERMISSION_READ_ENCRYPTED)));
                            PERMISSION_READ_ENCRYPTED)),
        characteristics.add(new Pair<>(UUID_MEDIA_STATE,
            entry(UUID_MEDIA_STATE,
                new CharacteristicData(CharId.MEDIA_STATE, ServiceFeature.MEDIA_STATE,
                    new CharacteristicData(CharId.MEDIA_STATE,
                            ServiceFeature.MEDIA_STATE,
                        // Mandatory notification if char. exists.
                        // Mandatory notification if char. exists.
                            ServiceFeature.MEDIA_STATE,
                        ServiceFeature.MEDIA_STATE, PROPERTY_READ | PROPERTY_NOTIFY,
                            PROPERTY_READ | PROPERTY_NOTIFY,
                        PERMISSION_READ_ENCRYPTED)));
                            PERMISSION_READ_ENCRYPTED)),
        characteristics.add(new Pair<>(UUID_MEDIA_CONTROL_POINT,
            entry(UUID_MEDIA_CONTROL_POINT,
                new CharacteristicData(CharId.MEDIA_CONTROL_POINT,
                new CharacteristicData(CharId.MEDIA_CONTROL_POINT,
                        ServiceFeature.MEDIA_CONTROL_POINT,
                        ServiceFeature.MEDIA_CONTROL_POINT,
                        // Mandatory notification if char. exists.
                        // Mandatory notification if char. exists.
                        ServiceFeature.MEDIA_CONTROL_POINT,
                        ServiceFeature.MEDIA_CONTROL_POINT,
                        PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY,
                        PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY,
                            PERMISSION_WRITE_ENCRYPTED)),
                        PERMISSION_WRITE_ENCRYPTED)));
            entry(UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED,
        characteristics.add(new Pair<>(UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED,
                new CharacteristicData(CharId.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED,
                new CharacteristicData(CharId.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED,
                        ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED,
                        ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED,
                            ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY,
                        ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY, PROPERTY_READ,
                            PROPERTY_READ,
                        PERMISSION_READ_ENCRYPTED)));
                            PERMISSION_READ_ENCRYPTED)),
        characteristics.add(new Pair<>(UUID_SEARCH_RESULT_OBJ_ID,
            entry(UUID_SEARCH_RESULT_OBJ_ID,
                new CharacteristicData(CharId.SEARCH_RESULT_OBJ_ID,
                new CharacteristicData(CharId.SEARCH_RESULT_OBJ_ID,
                        ServiceFeature.SEARCH_RESULT_OBJ_ID,
                        ServiceFeature.SEARCH_RESULT_OBJ_ID,
                        // Mandatory notification if char. exists.
                        // Mandatory notification if char. exists.
                            ServiceFeature.SEARCH_RESULT_OBJ_ID,
                        ServiceFeature.SEARCH_RESULT_OBJ_ID, PROPERTY_READ | PROPERTY_NOTIFY,
                            PROPERTY_READ | PROPERTY_NOTIFY,
                        PERMISSION_READ_ENCRYPTED)));
                            PERMISSION_READ_ENCRYPTED)),
        characteristics.add(new Pair<>(UUID_SEARCH_CONTROL_POINT,
            entry(UUID_SEARCH_CONTROL_POINT,
                new CharacteristicData(CharId.SEARCH_CONTROL_POINT,
                new CharacteristicData(CharId.SEARCH_CONTROL_POINT,
                        ServiceFeature.SEARCH_CONTROL_POINT,
                        ServiceFeature.SEARCH_CONTROL_POINT,
                        // Mandatory notification if char. exists.
                        // Mandatory notification if char. exists.
                        ServiceFeature.SEARCH_CONTROL_POINT,
                        ServiceFeature.SEARCH_CONTROL_POINT,
                        PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY,
                        PROPERTY_WRITE | PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY,
                            PERMISSION_WRITE_ENCRYPTED)),
                        PERMISSION_WRITE_ENCRYPTED)));
            entry(UUID_CONTENT_CONTROL_ID,
        characteristics.add(new Pair<>(UUID_CONTENT_CONTROL_ID,
                    new CharacteristicData(CharId.CONTENT_CONTROL_ID,
                new CharacteristicData(CharId.CONTENT_CONTROL_ID, ServiceFeature.CONTENT_CONTROL_ID,
                            ServiceFeature.CONTENT_CONTROL_ID,
                        // Notifications unsupported
                        // Notifications unsupported
                            0, PROPERTY_READ,
                        0, PROPERTY_READ, PERMISSION_READ_ENCRYPTED)));
                            PERMISSION_READ_ENCRYPTED)));
        return characteristics;
    }


    public void dump(StringBuilder sb) {
    public void dump(StringBuilder sb) {
        sb.append("\tMediaControlService instance:");
        sb.append("\tMediaControlService instance:");