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

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

Snap for 9115816 from be07b0aa to tm-qpr1-release

Change-Id: Ic3cf76b8bf21034565531652bd42d80c4a394b3e
parents 5b1f972a be07b0aa
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -1449,8 +1449,9 @@ public class HeadsetService extends ProfileService {
                LeAudioService leAudioService = mFactory.getLeAudioService();
                if (leAudioService != null) {
                    Log.i(TAG, "Make sure there is no le audio device active.");
                    leAudioService.setActiveDevice(null);
                    leAudioService.setInactiveForHfpHandover(mActiveDevice);
                }

                broadcastActiveDevice(mActiveDevice);
                int connectStatus = connectAudio(mActiveDevice);
                if (connectStatus != BluetoothStatusCodes.SUCCESS) {
@@ -1482,7 +1483,7 @@ public class HeadsetService extends ProfileService {
        }
    }

    int connectAudio() {
    public int connectAudio() {
        synchronized (mStateMachines) {
            BluetoothDevice device = mActiveDevice;
            if (device == null) {
+72 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.hfp.HeadsetService;
import com.android.bluetooth.mcp.McpService;
import com.android.bluetooth.tbs.TbsGatt;
import com.android.bluetooth.vc.VolumeControlService;
@@ -117,6 +118,7 @@ public class LeAudioService extends ProfileService {

    LeAudioNativeInterface mLeAudioNativeInterface;
    boolean mLeAudioNativeIsInitialized = false;
    BluetoothDevice mHfpHandoverDevice = null;
    LeAudioBroadcasterNativeInterface mLeAudioBroadcasterNativeInterface = null;
    @VisibleForTesting
    AudioManager mAudioManager;
@@ -331,6 +333,7 @@ public class LeAudioService extends ProfileService {
        mLeAudioNativeInterface.cleanup();
        mLeAudioNativeInterface = null;
        mLeAudioNativeIsInitialized = false;
        mHfpHandoverDevice = null;

        // Set the service and BLE devices as inactive
        setLeAudioService(null);
@@ -1173,6 +1176,36 @@ public class LeAudioService extends ProfileService {
        }
    }

    private void handleGroupIdleDuringCall() {
        if (mHfpHandoverDevice == null) {
            if (DBG) {
                Log.d(TAG, "There is no HFP handover");
            }
            return;
        }
        HeadsetService headsetService = mServiceFactory.getHeadsetService();
        if (headsetService == null) {
            if (DBG) {
                Log.d(TAG, "There is no HFP service available");
            }
            return;
        }

        BluetoothDevice activeHfpDevice = headsetService.getActiveDevice();
        if (activeHfpDevice == null) {
            if (DBG) {
                Log.d(TAG, "Make " + mHfpHandoverDevice + " active again ");
            }
            headsetService.setActiveDevice(mHfpHandoverDevice);
        } else {
            if (DBG) {
                Log.d(TAG, "Connect audio to " + activeHfpDevice);
            }
            headsetService.connectAudio();
        }
        mHfpHandoverDevice = null;
    }

    // Suppressed since this is part of a local process
    @SuppressLint("AndroidFrameworkRequiresPermission")
    void messageFromNative(LeAudioStackEvent stackEvent) {
@@ -1338,6 +1371,10 @@ public class LeAudioService extends ProfileService {
                    handleGroupTransitToInactive(groupId);
                    break;
                }
                case LeAudioStackEvent.GROUP_STATUS_TURNED_IDLE_DURING_CALL: {
                    handleGroupIdleDuringCall();
                    break;
                }
                default:
                    break;
            }
@@ -1746,6 +1783,20 @@ public class LeAudioService extends ProfileService {
        mLeAudioNativeInterface.setInCall(inCall);
    }

    /**
     * Set Inactive by HFP during handover
     */
    public void setInactiveForHfpHandover(BluetoothDevice hfpHandoverDevice) {
        if (!mLeAudioNativeIsInitialized) {
            Log.e(TAG, "Le Audio not initialized properly.");
            return;
        }
        if (getActiveGroupId() != LE_AUDIO_GROUP_ID_INVALID) {
            mHfpHandoverDevice = hfpHandoverDevice;
            setActiveDevice(null);
        }
    }

    /**
     * Set connection policy of the profile and connects it if connectionPolicy is
     * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is
@@ -2467,6 +2518,26 @@ public class LeAudioService extends ProfileService {
            }
        }

        @Override
        public void setInactiveForHfpHandover(BluetoothDevice hfpHandoverDevice,
                AttributionSource source,
                SynchronousResultReceiver receiver) {
            try {
                Objects.requireNonNull(source, "source cannot be null");
                Objects.requireNonNull(receiver, "receiver cannot be null");

                LeAudioService service = getService(source);
                if (service == null) {
                    throw new IllegalStateException("service is null");
                }
                enforceBluetoothPrivilegedPermission(service);
                service.setInactiveForHfpHandover(hfpHandoverDevice);
                receiver.send(null);
            } catch (RuntimeException e) {
                receiver.propagateException(e);
            }
        }

        @Override
        public void groupRemoveNode(int groupId, BluetoothDevice device,
                AttributionSource source, SynchronousResultReceiver receiver) {
@@ -2712,6 +2783,7 @@ public class LeAudioService extends ProfileService {
        ProfileService.println(sb, "  currentlyActiveGroupId: " + getActiveGroupId());
        ProfileService.println(sb, "  mActiveAudioOutDevice: " + mActiveAudioOutDevice);
        ProfileService.println(sb, "  mActiveAudioInDevice: " + mActiveAudioInDevice);
        ProfileService.println(sb, "  mHfpHandoverDevice:" + mHfpHandoverDevice);

        for (Map.Entry<Integer, LeAudioGroupDescriptor> entry : mGroupDescriptors.entrySet()) {
            LeAudioGroupDescriptor descriptor = entry.getValue();
+3 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ public class LeAudioStackEvent {

    static final int GROUP_STATUS_INACTIVE = 0;
    static final int GROUP_STATUS_ACTIVE = 1;
    static final int GROUP_STATUS_TURNED_IDLE_DURING_CALL = 2;

    static final int GROUP_NODE_ADDED = 1;
    static final int GROUP_NODE_REMOVED = 2;
@@ -192,6 +193,8 @@ public class LeAudioStackEvent {
                        return "GROUP_STATUS_ACTIVE";
                    case GROUP_STATUS_INACTIVE:
                        return "GROUP_STATUS_INACTIVE";
                    case GROUP_STATUS_TURNED_IDLE_DURING_CALL:
                        return "GROUP_STATUS_TURNED_IDLE_DURING_CALL";
                    default:
                        break;
                }
+93 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.bluetooth.gatt;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertThrows;

import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.TransportDiscoveryData;
import android.os.ParcelUuid;

import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.UUID;

/**
 * Test cases for {@link AdvertiseHelper}.
 */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class AdvertiseHelperTest {

    @Test
    public void advertiseDataToBytes() throws Exception {
        byte[] emptyBytes = AdvertiseHelper.advertiseDataToBytes(null, "");

        assertThat(emptyBytes.length).isEqualTo(0);

        int manufacturerId = 1;
        byte[] manufacturerData = new byte[]{
                0x30, 0x31, 0x32, 0x34
        };

        byte[] serviceData = new byte[]{
                0x10, 0x12, 0x14
        };

        byte[] transportDiscoveryData = new byte[]{
                0x40, 0x44, 0x48
        };

        AdvertiseData advertiseData = new AdvertiseData.Builder()
                .setIncludeDeviceName(true)
                .addManufacturerData(manufacturerId, manufacturerData)
                .setIncludeTxPowerLevel(true)
                .addServiceUuid(new ParcelUuid(UUID.randomUUID()))
                .addServiceData(new ParcelUuid(UUID.randomUUID()), serviceData)
                .addServiceSolicitationUuid(new ParcelUuid(UUID.randomUUID()))
                .addTransportDiscoveryData(new TransportDiscoveryData(transportDiscoveryData))
                .build();
        String deviceName = "TestDeviceName";

        int expectedAdvDataBytesLength = 87;
        byte[] advDataBytes = AdvertiseHelper.advertiseDataToBytes(advertiseData, deviceName);

        String deviceNameLong = "TestDeviceNameLongTestDeviceName";

        assertThat(advDataBytes.length).isEqualTo(expectedAdvDataBytesLength);

        int expectedAdvDataBytesLongNameLength = 99;
        byte[] advDataBytesLongName = AdvertiseHelper
                .advertiseDataToBytes(advertiseData, deviceNameLong);

        assertThat(advDataBytesLongName.length).isEqualTo(expectedAdvDataBytesLongNameLength);
    }

    @Test
    public void checkLength_withGT255_throwsException() {
        assertThrows(
                IllegalArgumentException.class,
                () -> AdvertiseHelper.check_length(0X00, 256)
        );
    }
}
 No newline at end of file
+53 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.bluetooth.gatt;

import static com.google.common.truth.Truth.assertThat;

import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Arrays;

/**
 * Test cases for {@link CallbackInfo}.
 */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class CallbackInfoTest {

    @Test
    public void callbackInfoBuilder() {
        String address = "TestAddress";
        int status = 0;
        int handle = 1;
        byte[] value = "Test Value Byte Array".getBytes();

        CallbackInfo callbackInfo = new CallbackInfo.Builder(address, status)
                .setHandle(handle)
                .setValue(value)
                .build();

        assertThat(callbackInfo.address).isEqualTo(address);
        assertThat(callbackInfo.status).isEqualTo(status);
        assertThat(callbackInfo.handle).isEqualTo(handle);
        assertThat(Arrays.equals(callbackInfo.value, value)).isTrue();
    }
}
Loading