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

Commit 5409f8bc authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8641798 from 3bac9628 to tm-qpr1-release

Change-Id: I68e2fed3fc41e6a654e795cb83ecfab2df3ff675
parents ab66d1fa 3bac9628
Loading
Loading
Loading
Loading
+11 −4
Original line number Original line Diff line number Diff line
@@ -17,9 +17,10 @@
  <option name="test-suite-tag" value="apct" />
  <option name="test-suite-tag" value="apct" />
  <option name="test-suite-tag" value="apct-native" />
  <option name="test-suite-tag" value="apct-native" />
  <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
  <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
  <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
  <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
        <option name="cleanup" value="true" />
        <option name="cleanup" value="true" />
        <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
        <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
        <option name="append-bitness" value="true" />
    </target_preparer>
    </target_preparer>
  <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
  <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
    <option name="run-command" value="settings put global ble_scan_always_enabled 0" />
    <option name="run-command" value="settings put global ble_scan_always_enabled 0" />
@@ -33,4 +34,10 @@
    <option name="module-name" value="{MODULE}" />
    <option name="module-name" value="{MODULE}" />
    <option name="run-test-as" value="0" />
    <option name="run-test-as" value="0" />
  </test>
  </test>

  <!-- Only run tests in MTS if the Bluetooth Mainline module is installed. -->
  <object type="module_controller"
          class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
      <option name="mainline-module-package-name" value="com.google.android.bluetooth" />
  </object>
</configuration>
</configuration>
+8 −8
Original line number Original line Diff line number Diff line
@@ -148,13 +148,14 @@ import java.time.Duration;
import java.util.ArrayDeque;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Map;
import java.util.Set;
import java.util.Set;
import java.util.UUID;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executor;
import java.util.function.Predicate;
import java.util.function.Predicate;
@@ -282,8 +283,7 @@ public class AdapterService extends Service {
    private boolean mQuietmode = false;
    private boolean mQuietmode = false;
    private HashMap<String, CallerInfo> mBondAttemptCallerInfo = new HashMap<>();
    private HashMap<String, CallerInfo> mBondAttemptCallerInfo = new HashMap<>();


    private final Map<UUID, RfcommListenerData> mBluetoothServerSockets =
    private final Map<UUID, RfcommListenerData> mBluetoothServerSockets = new ConcurrentHashMap<>();
            Collections.synchronizedMap(new HashMap<>());
    private final Executor mSocketServersExecutor = r -> new Thread(r).start();
    private final Executor mSocketServersExecutor = r -> new Thread(r).start();


    private AlarmManager mAlarmManager;
    private AlarmManager mAlarmManager;
@@ -1491,11 +1491,11 @@ public class AdapterService extends Service {
    }
    }


    private void stopRfcommServerSockets() {
    private void stopRfcommServerSockets() {
        synchronized (mBluetoothServerSockets) {
        Iterator<Map.Entry<UUID, RfcommListenerData>> socketsIterator =
            mBluetoothServerSockets.forEach((key, value) -> {
                mBluetoothServerSockets.entrySet().iterator();
                mBluetoothServerSockets.remove(key);
        while (socketsIterator.hasNext()) {
                value.closeServerAndPendingSockets(mHandler);
            socketsIterator.next().getValue().closeServerAndPendingSockets(mHandler);
            });
            socketsIterator.remove();
        }
        }
    }
    }


+26 −13
Original line number Original line Diff line number Diff line
@@ -139,7 +139,7 @@ public class LeAudioService extends ProfileService {
            mIsActive = false;
            mIsActive = false;
            mActiveContexts = ACTIVE_CONTEXTS_NONE;
            mActiveContexts = ACTIVE_CONTEXTS_NONE;
            mCodecStatus = null;
            mCodecStatus = null;
            mLostDevicesWhileStreaming = new ArrayList<>();
            mLostLeadDeviceWhileStreaming = null;
        }
        }


        public Boolean mIsConnected;
        public Boolean mIsConnected;
@@ -147,7 +147,7 @@ public class LeAudioService extends ProfileService {
        public Integer mActiveContexts;
        public Integer mActiveContexts;
        public BluetoothLeAudioCodecStatus mCodecStatus;
        public BluetoothLeAudioCodecStatus mCodecStatus;
        /* This can be non empty only for the streaming time */
        /* This can be non empty only for the streaming time */
        List<BluetoothDevice> mLostDevicesWhileStreaming;
        BluetoothDevice mLostLeadDeviceWhileStreaming;
    }
    }


    List<BluetoothLeAudioCodecConfig> mInputLocalCodecCapabilities = new ArrayList<>();
    List<BluetoothLeAudioCodecConfig> mInputLocalCodecCapabilities = new ArrayList<>();
@@ -1066,18 +1066,19 @@ public class LeAudioService extends ProfileService {
    }
    }


    private void clearLostDevicesWhileStreaming(LeAudioGroupDescriptor descriptor) {
    private void clearLostDevicesWhileStreaming(LeAudioGroupDescriptor descriptor) {
        for (BluetoothDevice dev : descriptor.mLostDevicesWhileStreaming) {
        if (DBG) {
            LeAudioStateMachine sm = mStateMachines.get(dev);
            Log.d(TAG, " lost dev: " + descriptor.mLostLeadDeviceWhileStreaming);
            if (sm == null) {
                continue;
        }
        }


        LeAudioStateMachine sm = mStateMachines.get(descriptor.mLostLeadDeviceWhileStreaming);
        if (sm != null) {
            LeAudioStackEvent stackEvent =
            LeAudioStackEvent stackEvent =
                new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
                new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
            stackEvent.device = dev;
            stackEvent.device = descriptor.mLostLeadDeviceWhileStreaming;
            stackEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED;
            stackEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED;
            sm.sendMessage(LeAudioStateMachine.STACK_EVENT, stackEvent);
            sm.sendMessage(LeAudioStateMachine.STACK_EVENT, stackEvent);
        }
        }
        descriptor.mLostLeadDeviceWhileStreaming = null;
    }
    }


    // Suppressed since this is part of a local process
    // Suppressed since this is part of a local process
@@ -1110,14 +1111,17 @@ public class LeAudioService extends ProfileService {
                                        mActiveAudioOutDevice)
                                        mActiveAudioOutDevice)
                                        || Objects.equals(device, mActiveAudioInDevice))
                                        || Objects.equals(device, mActiveAudioInDevice))
                                        && (getConnectedPeerDevices(groupId).size() > 1)) {
                                        && (getConnectedPeerDevices(groupId).size() > 1)) {
                                    descriptor.mLostDevicesWhileStreaming.add(device);

                                    if (DBG) Log.d(TAG, "Adding to lost devices : " + device);
                                    descriptor.mLostLeadDeviceWhileStreaming = device;
                                    return;
                                    return;
                                }
                                }
                                break;
                                break;
                            case LeAudioStackEvent.CONNECTION_STATE_CONNECTED:
                            case LeAudioStackEvent.CONNECTION_STATE_CONNECTED:
                            case LeAudioStackEvent.CONNECTION_STATE_CONNECTING:
                            case LeAudioStackEvent.CONNECTION_STATE_CONNECTING:
                                if (descriptor != null) {
                                if (descriptor != null) {
                                    descriptor.mLostDevicesWhileStreaming.remove(device);
                                    if (DBG) Log.d(TAG, "Removing from lost devices : " + device);
                                    descriptor.mLostLeadDeviceWhileStreaming = null;
                                    /* Try to connect other devices from the group */
                                    /* Try to connect other devices from the group */
                                    connectSet(device);
                                    connectSet(device);
                                }
                                }
@@ -1254,6 +1258,7 @@ public class LeAudioService extends ProfileService {
                                    ACTIVE_CONTEXTS_NONE, descriptor.mIsActive);
                                    ACTIVE_CONTEXTS_NONE, descriptor.mIsActive);
                            notifyGroupStatus = true;
                            notifyGroupStatus = true;
                            /* Clear lost devices */
                            /* Clear lost devices */
                            if (DBG) Log.d(TAG, "Clear for group: " + groupId);
                            clearLostDevicesWhileStreaming(descriptor);
                            clearLostDevicesWhileStreaming(descriptor);
                        }
                        }
                    } else {
                    } else {
@@ -1538,6 +1543,15 @@ public class LeAudioService extends ProfileService {
                return;
                return;
            }
            }


            List<BluetoothDevice> connectedDevices = getConnectedPeerDevices(myGroupId);
            /* Let's check if the last connected device is really connected */
            if (connectedDevices.size() == 1
                    && Objects.equals(connectedDevices.get(0),
                            descriptor.mLostLeadDeviceWhileStreaming)) {
                clearLostDevicesWhileStreaming(descriptor);
                return;
            }

            if (getConnectedPeerDevices(myGroupId).isEmpty()){
            if (getConnectedPeerDevices(myGroupId).isEmpty()){
                descriptor.mIsConnected = false;
                descriptor.mIsConnected = false;
                if (descriptor.mIsActive) {
                if (descriptor.mIsActive) {
@@ -2584,9 +2598,8 @@ public class LeAudioService extends ProfileService {
            ProfileService.println(sb, "    mActiveContexts: " + descriptor.mActiveContexts);
            ProfileService.println(sb, "    mActiveContexts: " + descriptor.mActiveContexts);
            ProfileService.println(sb, "    group lead: " + getConnectedGroupLeadDevice(groupId));
            ProfileService.println(sb, "    group lead: " + getConnectedGroupLeadDevice(groupId));
            ProfileService.println(sb, "    first device: " + getFirstDeviceFromGroup(groupId));
            ProfileService.println(sb, "    first device: " + getFirstDeviceFromGroup(groupId));
            for (BluetoothDevice dev : descriptor.mLostDevicesWhileStreaming) {
            ProfileService.println(sb, "    lost lead device: "
                ProfileService.println(sb, "        lost device: " + dev);
                    + descriptor.mLostLeadDeviceWhileStreaming);
            }
        }
        }
    }
    }
}
}
+161 −0
Original line number Original line Diff line number Diff line
@@ -26,7 +26,11 @@ import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;


import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice;
@@ -42,6 +46,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.AudioManager;
import android.media.BluetoothProfileConnectionInfo;
import android.os.ParcelUuid;
import android.os.ParcelUuid;


import androidx.test.InstrumentationRegistry;
import androidx.test.InstrumentationRegistry;
@@ -68,6 +73,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashSet;
import java.util.List;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeoutException;


@@ -457,6 +463,23 @@ public class LeAudioServiceTest {
                .isEqualTo(BluetoothProfile.STATE_DISCONNECTED);
                .isEqualTo(BluetoothProfile.STATE_DISCONNECTED);
    }
    }


    private void injectNoVerifyDeviceConnected(BluetoothDevice device) {
        generateUnexpectedConnectionMessageFromNative(device,
                LeAudioStackEvent.CONNECTION_STATE_CONNECTED,
                LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED);
    }

    private void injectAndVerifyDeviceDisconnected(BluetoothDevice device) {
        generateConnectionMessageFromNative(device,
                LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED,
                LeAudioStackEvent.CONNECTION_STATE_CONNECTED);
    }

    private void injectNoVerifyDeviceDisconnected(BluetoothDevice device) {
        generateUnexpectedConnectionMessageFromNative(device,
                LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED,
                LeAudioStackEvent.CONNECTION_STATE_CONNECTED);
    }
    /**
    /**
     * Test that the outgoing connect/disconnect and audio switch is successful.
     * Test that the outgoing connect/disconnect and audio switch is successful.
     */
     */
@@ -1220,4 +1243,142 @@ public class LeAudioServiceTest {
        onGroupCodecConfChangedCallbackCalled = false;
        onGroupCodecConfChangedCallbackCalled = false;
        mService.mLeAudioCallbacks.unregister(leAudioCallbacks);
        mService.mLeAudioCallbacks.unregister(leAudioCallbacks);
    }
    }

    private void verifyActiveDeviceStateIntent(int timeoutMs, BluetoothDevice device) {
        Intent intent = TestUtils.waitForIntent(timeoutMs, mDeviceQueueMap.get(device));
        assertThat(intent).isNotNull();
        assertThat(intent.getAction())
                .isEqualTo(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED);
        assertThat(device).isEqualTo(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
    }

    /**
     * Test native interface group status message handling
     */
    @Test
    public void testLeadGroupDeviceDisconnects() {
        int groupId = 1;
        int direction = 1;
        int snkAudioLocation = 3;
        int srcAudioLocation = 4;
        int availableContexts = 5;
        int groupStatus = LeAudioStackEvent.GROUP_STATUS_ACTIVE;
        BluetoothDevice leadDevice;
        BluetoothDevice memberDevice = mLeftDevice;

        doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class));
        connectTestDevice(mLeftDevice, groupId);
        connectTestDevice(mRightDevice, groupId);

        leadDevice = mService.getConnectedGroupLeadDevice(groupId);
        if (Objects.equals(leadDevice, mLeftDevice)) {
                memberDevice = mRightDevice;
        }

        assertThat(mService.setActiveDevice(leadDevice)).isTrue();

        //Add location support
        LeAudioStackEvent audioConfChangedEvent =
                new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED);
        audioConfChangedEvent.valueInt1 = direction;
        audioConfChangedEvent.valueInt2 = groupId;
        audioConfChangedEvent.valueInt3 = snkAudioLocation;
        audioConfChangedEvent.valueInt4 = srcAudioLocation;
        audioConfChangedEvent.valueInt5 = availableContexts;
        mService.messageFromNative(audioConfChangedEvent);

        //Set group and device as active
        LeAudioStackEvent groupStatusChangedEvent =
                new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED);
        groupStatusChangedEvent.valueInt1 = groupId;
        groupStatusChangedEvent.valueInt2 = groupStatus;
        mService.messageFromNative(groupStatusChangedEvent);

        assertThat(mService.getActiveDevices().contains(leadDevice)).isTrue();
        verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(eq(leadDevice), any(),
                        any(BluetoothProfileConnectionInfo.class));

        verifyActiveDeviceStateIntent(TIMEOUT_MS, leadDevice);
        injectNoVerifyDeviceDisconnected(leadDevice);

        // We should not change the audio device
        assertThat(mService.getConnectionState(leadDevice))
                .isEqualTo(BluetoothProfile.STATE_CONNECTED);

        injectAndVerifyDeviceDisconnected(memberDevice);

        // Verify the connection state broadcast, and that we are in Connecting state
        verifyConnectionStateIntent(TIMEOUT_MS, leadDevice, BluetoothProfile.STATE_DISCONNECTED,
                BluetoothProfile.STATE_CONNECTED);

        verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(any(), eq(leadDevice),
                any(BluetoothProfileConnectionInfo.class));

    }

    /**
     * Test native interface group status message handling
     */
    @Test
    public void testLeadGroupDeviceReconnects() {
        int groupId = 1;
        int direction = 1;
        int snkAudioLocation = 3;
        int srcAudioLocation = 4;
        int availableContexts = 5;
        int groupStatus = LeAudioStackEvent.GROUP_STATUS_ACTIVE;
        BluetoothDevice leadDevice;
        BluetoothDevice memberDevice = mLeftDevice;

        doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class));
        connectTestDevice(mLeftDevice, groupId);
        connectTestDevice(mRightDevice, groupId);

        leadDevice = mService.getConnectedGroupLeadDevice(groupId);
        if (Objects.equals(leadDevice, mLeftDevice)) {
                memberDevice = mRightDevice;
        }

        assertThat(mService.setActiveDevice(leadDevice)).isTrue();

        //Add location support
        LeAudioStackEvent audioConfChangedEvent =
                new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED);
        audioConfChangedEvent.valueInt1 = direction;
        audioConfChangedEvent.valueInt2 = groupId;
        audioConfChangedEvent.valueInt3 = snkAudioLocation;
        audioConfChangedEvent.valueInt4 = srcAudioLocation;
        audioConfChangedEvent.valueInt5 = availableContexts;
        mService.messageFromNative(audioConfChangedEvent);

        //Set group and device as active
        LeAudioStackEvent groupStatusChangedEvent =
                new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED);
        groupStatusChangedEvent.valueInt1 = groupId;
        groupStatusChangedEvent.valueInt2 = groupStatus;
        mService.messageFromNative(groupStatusChangedEvent);

        assertThat(mService.getActiveDevices().contains(leadDevice)).isTrue();
        verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(eq(leadDevice), any(),
                        any(BluetoothProfileConnectionInfo.class));

        verifyActiveDeviceStateIntent(TIMEOUT_MS, leadDevice);
        /* We don't want to distribute DISCONNECTION event, instead will try to reconnect
         * (in native)
         */
        injectNoVerifyDeviceDisconnected(leadDevice);
        assertThat(mService.getConnectionState(leadDevice))
                .isEqualTo(BluetoothProfile.STATE_CONNECTED);

        /* Reconnect device, there should be no intent about that, as device was pretending
         * connected
         */
        injectNoVerifyDeviceConnected(leadDevice);

        injectAndVerifyDeviceDisconnected(memberDevice);
        injectAndVerifyDeviceDisconnected(leadDevice);

        verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(eq(null), eq(leadDevice),
                any(BluetoothProfileConnectionInfo.class));
    }
}
}
+9 −3
Original line number Original line Diff line number Diff line
@@ -1558,9 +1558,15 @@ class CsisClientImpl : public CsisClient {
        OnGattNotification(p_data->notify);
        OnGattNotification(p_data->notify);
        break;
        break;


      case BTA_GATTC_ENC_CMPL_CB_EVT:
      case BTA_GATTC_ENC_CMPL_CB_EVT: {
        OnLeEncryptionComplete(p_data->enc_cmpl.remote_bda, BTM_SUCCESS);
        uint8_t encryption_status;
        break;
        if (BTM_IsEncrypted(p_data->enc_cmpl.remote_bda, BT_TRANSPORT_LE)) {
          encryption_status = BTM_SUCCESS;
        } else {
          encryption_status = BTM_FAILED_ON_SECURITY;
        }
        OnLeEncryptionComplete(p_data->enc_cmpl.remote_bda, encryption_status);
      } break;


      case BTA_GATTC_SRVC_CHG_EVT:
      case BTA_GATTC_SRVC_CHG_EVT:
        OnGattServiceChangeEvent(p_data->remote_bda);
        OnGattServiceChangeEvent(p_data->remote_bda);
Loading