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

Commit 0c237080 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 9569386 from 13b67d0c to udc-release

Change-Id: Ia987b1a1e1204a02b23688bd53ac0af817b615a7
parents 44807dc0 13b67d0c
Loading
Loading
Loading
Loading
+73 −48
Original line number Diff line number Diff line
@@ -182,10 +182,8 @@ public class LeAudioService extends ProfileService {
    private BroadcastReceiver mMuteStateChangedReceiver;
    private int mStoredRingerMode = -1;
    private Handler mHandler = new Handler(Looper.getMainLooper());
    private final AudioManagerAddAudioDeviceCallback mAudioManagerAddAudioDeviceCallback =
            new AudioManagerAddAudioDeviceCallback();
    private final AudioManagerRemoveAudioDeviceCallback mAudioManagerRemoveAudioDeviceCallback =
            new AudioManagerRemoveAudioDeviceCallback();
    private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback =
            new AudioManagerAudioDeviceCallback();

    private final Map<Integer, Integer> mBroadcastStateMap = new HashMap<>();
    private final Map<Integer, Boolean> mBroadcastsPlaybackMap = new HashMap<>();
@@ -281,6 +279,9 @@ public class LeAudioService extends ProfileService {
        mTmapGattServer = LeAudioObjectsFactory.getInstance().getTmapGattServer(this);
        mTmapGattServer.start(tmapRoleMask);

        mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback,
                       mHandler);

        // Mark service as started
        setLeAudioService(this);

@@ -399,8 +400,7 @@ public class LeAudioService extends ProfileService {
            }
        }

        mAudioManager.unregisterAudioDeviceCallback(mAudioManagerAddAudioDeviceCallback);
        mAudioManager.unregisterAudioDeviceCallback(mAudioManagerRemoveAudioDeviceCallback);
        mAudioManager.unregisterAudioDeviceCallback(mAudioManagerAudioDeviceCallback);

        mAdapterService = null;
        mAudioManager = null;
@@ -995,54 +995,85 @@ public class LeAudioService extends ProfileService {
     * is added or removed.
     */
    @VisibleForTesting
    void notifyActiveDeviceChanged() {
    void notifyActiveDeviceChanged(BluetoothDevice device) {
        if (DBG) {
            Log.d(TAG, "Notify Active device changed." + device
                    + ". Currently active device is " + mActiveAudioOutDevice);
        }

        Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE,
                mActiveAudioOutDevice != null ? mActiveAudioOutDevice : mActiveAudioInDevice);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        sendBroadcast(intent, BLUETOOTH_CONNECT);
    }

    /* Notifications of audio device disconnection events. */
    private class AudioManagerRemoveAudioDeviceCallback extends AudioDeviceCallback {
    /* Notifications of audio device connection/disconn events. */
    private class AudioManagerAudioDeviceCallback extends AudioDeviceCallback {
        @Override
        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
            if (mAudioManager == null) {
        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
            if (mAudioManager == null || mAdapterService == null)  {
                Log.e(TAG, "Callback called when LeAudioService is stopped");
                return;
            }

            for (AudioDeviceInfo deviceInfo : removedDevices) {
                if (deviceInfo.getType() == AudioDeviceInfo.TYPE_BLE_HEADSET
                        || deviceInfo.getType() == AudioDeviceInfo.TYPE_BLE_SPEAKER) {
                    notifyActiveDeviceChanged();
                    if (DBG) {
                        Log.d(TAG, " onAudioDevicesRemoved: device type: " + deviceInfo.getType());
            for (AudioDeviceInfo deviceInfo : addedDevices) {
                if ((deviceInfo.getType() != AudioDeviceInfo.TYPE_BLE_HEADSET)
                        && (deviceInfo.getType() != AudioDeviceInfo.TYPE_BLE_SPEAKER)) {
                    continue;
                }
                    mAudioManager.unregisterAudioDeviceCallback(this);

                String address = deviceInfo.getAddress();
                if (address.equals("00:00:00:00:00:00")) {
                    continue;
                }

                byte[] addressBytes = Utils.getBytesFromAddress(address);
                BluetoothDevice device = mAdapterService.getDeviceFromByte(addressBytes);

                if (DBG) {
                    Log.d(TAG, " onAudioDevicesAdded: " + device + ", device type: "
                            + deviceInfo.getType() + ", isSink: " + deviceInfo.isSink()
                            + " isSource: " + deviceInfo.isSource());
                }

                if ((deviceInfo.isSink() && !device.equals(mActiveAudioOutDevice))
                        || (deviceInfo.isSource() && !device.equals(mActiveAudioInDevice))) {
                    Log.e(TAG, "Added device does not match to the one activated here. ("
                            + device + " != " + mActiveAudioOutDevice
                            + " / " + mActiveAudioInDevice + ")");
                    continue;
                }

                notifyActiveDeviceChanged(device);
                return;
            }
        }

    /* Notifications of audio device connection events. */
    private class AudioManagerAddAudioDeviceCallback extends AudioDeviceCallback {
        @Override
        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
            if (mAudioManager == null) {
        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
            if (mAudioManager == null || mAdapterService == null) {
                Log.e(TAG, "Callback called when LeAudioService is stopped");
                return;
            }

            for (AudioDeviceInfo deviceInfo : addedDevices) {
                if (deviceInfo.getType() == AudioDeviceInfo.TYPE_BLE_HEADSET
                        || deviceInfo.getType() == AudioDeviceInfo.TYPE_BLE_SPEAKER) {
                    notifyActiveDeviceChanged();
                    if (DBG) {
                        Log.d(TAG, " onAudioDevicesAdded: device type: " + deviceInfo.getType());
            for (AudioDeviceInfo deviceInfo : removedDevices) {
                if ((deviceInfo.getType() != AudioDeviceInfo.TYPE_BLE_HEADSET)
                        && (deviceInfo.getType() != AudioDeviceInfo.TYPE_BLE_SPEAKER)) {
                    continue;
                }
                    mAudioManager.unregisterAudioDeviceCallback(this);

                String address = deviceInfo.getAddress();
                if (address.equals("00:00:00:00:00:00")) {
                    continue;
                }

                if (DBG) {
                    Log.d(TAG, " onAudioDevicesRemoved: " + address + ", device type: "
                            + deviceInfo.getType() + ", isSink: " + deviceInfo.isSink()
                            + " isSource: " + deviceInfo.isSource()
                            + ", mActiveAudioInDevice: " + mActiveAudioInDevice
                            + ", mActiveAudioOutDevice: " +  mActiveAudioOutDevice);
                }
            }
        }
@@ -1077,20 +1108,6 @@ public class LeAudioService extends ProfileService {
                    + ", " + mActiveAudioInDevice);
        }

        /* Active device changed, there is need to inform about new active LE Audio device */
        if (isNewActiveOutDevice || isNewActiveInDevice) {
            /* Register for new device connection/disconnection in Audio Manager */
            if (mActiveAudioOutDevice != null || mActiveAudioInDevice != null) {
                /* Register for any device connection in case if any of devices become connected */
                mAudioManager.registerAudioDeviceCallback(mAudioManagerAddAudioDeviceCallback,
                        mHandler);
            } else {
                /* Register for disconnection if active devices become non-active */
                mAudioManager.registerAudioDeviceCallback(mAudioManagerRemoveAudioDeviceCallback,
                        mHandler);
            }
        }

        if (isNewActiveOutDevice) {
            int volume = IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME;

@@ -1112,6 +1129,14 @@ public class LeAudioService extends ProfileService {
                            false));
        }

        if ((mActiveAudioOutDevice == null) && (mActiveAudioInDevice == null)) {
            /* Notify about inactive device as soon as possible.
             * When adding new device, wait with notification until AudioManager is ready
             * with adding the device.
             */
            notifyActiveDeviceChanged(null);
        }

        return mActiveAudioOutDevice != null;
    }

+3 −3
Original line number Diff line number Diff line
@@ -1147,7 +1147,7 @@ public class LeAudioServiceTest {
        /* Since LeAudioService called AudioManager - assume Audio manager calles properly callback
        * mAudioManager.onAudioDeviceAdded
        */
        mService.notifyActiveDeviceChanged();
        mService.notifyActiveDeviceChanged(mSingleDevice);

        String action = BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED;
        Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mDeviceQueueMap.get(mSingleDevice));
@@ -1363,7 +1363,7 @@ public class LeAudioServiceTest {
        /* Since LeAudioService called AudioManager - assume Audio manager calles properly callback
         * mAudioManager.onAudioDeviceAdded
         */
        mService.notifyActiveDeviceChanged();
        mService.notifyActiveDeviceChanged(leadDevice);
        doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService).getBondState(leadDevice);
        verifyActiveDeviceStateIntent(AUDIO_MANAGER_DEVICE_ADD_TIMEOUT_MS, leadDevice);
        injectNoVerifyDeviceDisconnected(leadDevice);
@@ -1432,7 +1432,7 @@ public class LeAudioServiceTest {
        /* Since LeAudioService called AudioManager - assume Audio manager calles properly callback
         * mAudioManager.onAudioDeviceAdded
         */
        mService.notifyActiveDeviceChanged();
        mService.notifyActiveDeviceChanged(leadDevice);

        verifyActiveDeviceStateIntent(AUDIO_MANAGER_DEVICE_ADD_TIMEOUT_MS, leadDevice);
        /* We don't want to distribute DISCONNECTION event, instead will try to reconnect
+1 −1
Original line number Diff line number Diff line
@@ -207,7 +207,7 @@ class GAPProxy(ProfileProxy):

        self.host.StartAdvertising(
            own_address_type=OwnAddressType.PUBLIC,
            data=DataTypes(incomplete_service_class_uuids128=["955798ce-3022-455c-b759-ee8edcd73d1a"],))
            data=DataTypes(complete_service_class_uuids128=["955798ce-3022-455c-b759-ee8edcd73d1a"],))
        return "OK"

    @assert_description
+23 −15
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ import android.bluetooth.BluetoothDevice.TRANSPORT_BREDR
import android.bluetooth.BluetoothDevice.TRANSPORT_LE
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile
import android.bluetooth.BluetoothUuid;
import android.bluetooth.BluetoothUuid
import android.bluetooth.le.AdvertiseCallback
import android.bluetooth.le.AdvertiseData
import android.bluetooth.le.AdvertiseSettings
@@ -550,21 +550,23 @@ class Host(
          val dataTypesRequest = request.data

          if (
            !dataTypesRequest.getCompleteServiceClassUuids16List().isEmpty() or
              !dataTypesRequest.getCompleteServiceClassUuids32List().isEmpty() or
              !dataTypesRequest.getCompleteServiceClassUuids128List().isEmpty()
            !dataTypesRequest.getIncompleteServiceClassUuids16List().isEmpty() or
              !dataTypesRequest.getIncompleteServiceClassUuids32List().isEmpty() or
              !dataTypesRequest.getIncompleteServiceClassUuids128List().isEmpty()
          ) {
            Log.e(TAG, "Complete Service Class Uuids not supported")
            Log.e(TAG, "Incomplete Service Class Uuids not supported")
            throw Status.UNKNOWN.asException()
          }

          for (service_uuid in dataTypesRequest.getIncompleteServiceClassUuids16List()) {
            advertisingDataBuilder.addServiceUuid(ParcelUuid.fromString(service_uuid))
          for (service_uuid in dataTypesRequest.getCompleteServiceClassUuids16List()) {
            val uuid16 = "0000${service_uuid}-0000-1000-8000-00805F9B34FB"
            advertisingDataBuilder.addServiceUuid(ParcelUuid.fromString(uuid16))
          }
          for (service_uuid in dataTypesRequest.getIncompleteServiceClassUuids32List()) {
          for (service_uuid in dataTypesRequest.getCompleteServiceClassUuids32List()) {
            val uuid32 = "${service_uuid}-0000-1000-8000-00805F9B34FB"
            advertisingDataBuilder.addServiceUuid(ParcelUuid.fromString(service_uuid))
          }
          for (service_uuid in dataTypesRequest.getIncompleteServiceClassUuids128List()) {
          for (service_uuid in dataTypesRequest.getCompleteServiceClassUuids128List()) {
            advertisingDataBuilder.addServiceUuid(ParcelUuid.fromString(service_uuid))
          }

@@ -651,18 +653,24 @@ class Host(
                if (BluetoothUuid.is16BitUuid(parcelUuid)) {
                  val uuid16 = parcelUuid.uuid.toString().substring(4, 8).uppercase()
                  dataTypesBuilder.addIncompleteServiceClassUuids16(uuid16)
                  dataTypesBuilder.putServiceDataUuid16(uuid16,
                                                        ByteString.copyFrom(serviceDataEntry.value))
                  dataTypesBuilder.putServiceDataUuid16(
                    uuid16,
                    ByteString.copyFrom(serviceDataEntry.value)
                  )
                } else if (BluetoothUuid.is32BitUuid(parcelUuid)) {
                  val uuid32 = parcelUuid.uuid.toString().substring(0, 8).uppercase()
                  dataTypesBuilder.addIncompleteServiceClassUuids32(uuid32)
                  dataTypesBuilder.putServiceDataUuid32(uuid32,
                                                        ByteString.copyFrom(serviceDataEntry.value))
                  dataTypesBuilder.putServiceDataUuid32(
                    uuid32,
                    ByteString.copyFrom(serviceDataEntry.value)
                  )
                } else {
                  val uuid128 = parcelUuid.uuid.toString().uppercase()
                  dataTypesBuilder.addIncompleteServiceClassUuids128(uuid128)
                  dataTypesBuilder.putServiceDataUuid128(uuid128,
                                                         ByteString.copyFrom(serviceDataEntry.value))
                  dataTypesBuilder.putServiceDataUuid128(
                    uuid128,
                    ByteString.copyFrom(serviceDataEntry.value)
                  )
                }
              }
              // Flags DataTypes CSSv10 1.3 Flags
+11 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.IntentFilter
import android.util.Log
import com.google.protobuf.BoolValue
import com.google.protobuf.Empty
import io.grpc.Status
import io.grpc.stub.StreamObserver
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -75,8 +76,16 @@ class SecurityStorage(private val context: Context) : SecurityStorageImplBase()

  override fun deleteBond(request: DeleteBondRequest, responseObserver: StreamObserver<Empty>) {
    grpcUnary(globalScope, responseObserver) {
      check(request.getAddressCase() == DeleteBondRequest.AddressCase.PUBLIC)
      val bluetoothDevice = request.public.toBluetoothDevice(bluetoothAdapter)
      val (address, type) =
        when (request.getAddressCase()!!) {
          DeleteBondRequest.AddressCase.PUBLIC ->
            Pair(request.public, BluetoothDevice.ADDRESS_TYPE_PUBLIC)
          DeleteBondRequest.AddressCase.RANDOM ->
            Pair(request.random, BluetoothDevice.ADDRESS_TYPE_RANDOM)
          DeleteBondRequest.AddressCase.ADDRESS_NOT_SET -> throw Status.UNKNOWN.asException()
        }
      val bluetoothDevice =
        bluetoothAdapter.getRemoteLeDevice(address.decodeAsMacAddressToString(), type)
      Log.i(TAG, "deleteBond: device=$bluetoothDevice")

      val unbonded =
Loading