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

Commit 86fe8ba1 authored by Android Build Merger (Role)'s avatar Android Build Merger (Role) Committed by Android (Google) Code Review
Browse files

Merge changes from topic "am-85dda005ca6342199835b5ce487e1702" into pi-dev-plus-aosp

* changes:
  Merge "Add SapProfile to LocalBluetoothProfileManager (1/2)" am: fce85954 am: 6ac6aead
  Merge "Add SapProfile to LocalBluetoothProfileManager (1/2)" am: fce85954
  Add SapProfile to LocalBluetoothProfileManager (1/2) am: 2be42b97
parents 79625e97 61d67acd
Loading
Loading
Loading
Loading
+28 −8
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.bluetooth.BluetoothMapClient;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothPbap;
import android.bluetooth.BluetoothPbapClient;
import android.bluetooth.BluetoothSap;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.content.Context;
@@ -98,6 +99,7 @@ public class LocalBluetoothProfileManager {
    private final boolean mUsePbapPce;
    private final boolean mUseMapClient;
    private HearingAidProfile mHearingAidProfile;
    private SapProfile mSapProfile;

    /**
     * Mapping from profile name, e.g. "HEADSET" to profile object.
@@ -194,12 +196,14 @@ public class LocalBluetoothProfileManager {
        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink)) {
            if (mA2dpSinkProfile == null) {
                if(DEBUG) Log.d(TAG, "Adding local A2DP Sink profile");
                mA2dpSinkProfile = new A2dpSinkProfile(mContext, mLocalAdapter, mDeviceManager, this);
                mA2dpSinkProfile = new A2dpSinkProfile(mContext, mLocalAdapter,
                        mDeviceManager, this);
                addProfile(mA2dpSinkProfile, A2dpSinkProfile.NAME,
                        BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED);
            }
        } else if (mA2dpSinkProfile != null) {
            Log.w(TAG, "Warning: A2DP Sink profile was previously added but the UUID is now missing.");
            Log.w(TAG, "Warning: A2DP Sink profile was previously added but the "
                    + "UUID is now missing.");
        }

        // Headset / Handsfree
@@ -215,7 +219,8 @@ public class LocalBluetoothProfileManager {
                        BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
            }
        } else if (mHeadsetProfile != null) {
            Log.w(TAG, "Warning: HEADSET profile was previously added but the UUID is now missing.");
            Log.w(TAG, "Warning: HEADSET profile was previously added but the "
                    + "UUID is now missing.");
        }

        // Headset HF
@@ -247,7 +252,8 @@ public class LocalBluetoothProfileManager {
            }
        } else if (mMapClientProfile != null) {
            Log.w(TAG,
                    "Warning: MAP Client profile was previously added but the UUID is now missing.");
                    "Warning: MAP Client profile was previously added but the "
                            + "UUID is now missing.");
        } else {
            Log.d(TAG, "MAP Client Uuid not found.");
        }
@@ -282,14 +288,23 @@ public class LocalBluetoothProfileManager {
        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HearingAid)) {
            if (mHearingAidProfile == null) {
                if(DEBUG) Log.d(TAG, "Adding local Hearing Aid profile");
                mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager, this);
                mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter,
                        mDeviceManager, this);
                addProfile(mHearingAidProfile, HearingAidProfile.NAME,
                        BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
            }
        } else if (mHearingAidProfile != null) {
            Log.w(TAG, "Warning: Hearing Aid profile was previously added but the UUID is now missing.");
            Log.w(TAG, "Warning: Hearing Aid profile was previously added but the "
                    + "UUID is now missing.");
        }

        // SAP
        if (mSapProfile == null && BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.SAP)) {
            Log.d(TAG, "Adding local SAP profile");
            mSapProfile = new SapProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addProfile(mSapProfile, SapProfile.NAME,
                BluetoothSap.ACTION_CONNECTION_STATE_CHANGED);
        }
        mEventManager.registerProfileIntentReceiver();

        // There is no local SDP record for HID and Settings app doesn't control PBAP Server.
@@ -646,6 +661,11 @@ public class LocalBluetoothProfileManager {
            removedProfiles.remove(mHearingAidProfile);
        }

        if (mSapProfile != null && BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.SAP)) {
            profiles.add(mSapProfile);
            removedProfiles.remove(mSapProfile);
        }

        if (DEBUG) {
            Log.d(TAG,"New Profiles" + profiles.toString());
        }
+27 −29
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import java.util.List;
 */
final class SapProfile implements LocalBluetoothProfile {
    private static final String TAG = "SapProfile";
    private static boolean V = true;

    private BluetoothSap mService;
    private boolean mIsProfileReady;
@@ -59,7 +58,7 @@ final class SapProfile implements LocalBluetoothProfile {
            implements BluetoothProfile.ServiceListener {

        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            if (V) Log.d(TAG,"Bluetooth service connected");
            Log.d(TAG, "Bluetooth service connected, profile:" + profile);
            mService = (BluetoothSap) proxy;
            // We just bound to the service, so refresh the UI for any connected SAP devices.
            List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -81,7 +80,7 @@ final class SapProfile implements LocalBluetoothProfile {
        }

        public void onServiceDisconnected(int profile) {
            if (V) Log.d(TAG,"Bluetooth service disconnected");
            Log.d(TAG, "Bluetooth service disconnected, profile:" + profile);
            mProfileManager.callServiceDisconnectedListeners();
            mIsProfileReady=false;
        }
@@ -115,50 +114,47 @@ final class SapProfile implements LocalBluetoothProfile {
    }

    public boolean connect(BluetoothDevice device) {
        if (mService == null) return false;
        List<BluetoothDevice> sinks = mService.getConnectedDevices();
        if (sinks != null) {
            for (BluetoothDevice sink : sinks) {
                mService.disconnect(sink);
            }
        if (mService == null) {
            return false;
        }
        return mService.connect(device);
    }

    public boolean disconnect(BluetoothDevice device) {
        if (mService == null) return false;
        List<BluetoothDevice> deviceList = mService.getConnectedDevices();
        if (!deviceList.isEmpty() && deviceList.get(0).equals(device)) {
        if (mService == null) {
            return false;
        }
        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
        }
        return mService.disconnect(device);
        } else {
            return false;
        }
    }

    public int getConnectionStatus(BluetoothDevice device) {
        if (mService == null) return BluetoothProfile.STATE_DISCONNECTED;
        List<BluetoothDevice> deviceList = mService.getConnectedDevices();

        return !deviceList.isEmpty() && deviceList.get(0).equals(device)
                ? mService.getConnectionState(device)
                : BluetoothProfile.STATE_DISCONNECTED;
        if (mService == null) {
            return BluetoothProfile.STATE_DISCONNECTED;
        }
        return mService.getConnectionState(device);
    }

    public boolean isPreferred(BluetoothDevice device) {
        if (mService == null) return false;
        if (mService == null) {
            return false;
        }
        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
    }

    public int getPreferred(BluetoothDevice device) {
        if (mService == null) return BluetoothProfile.PRIORITY_OFF;
        if (mService == null) {
            return BluetoothProfile.PRIORITY_OFF;
        }
        return mService.getPriority(device);
    }

    public void setPreferred(BluetoothDevice device, boolean preferred) {
        if (mService == null) return;
        if (mService == null) {
            return;
        }
        if (preferred) {
            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
@@ -169,7 +165,9 @@ final class SapProfile implements LocalBluetoothProfile {
    }

    public List<BluetoothDevice> getConnectedDevices() {
        if (mService == null) return new ArrayList<BluetoothDevice>(0);
        if (mService == null) {
            return new ArrayList<BluetoothDevice>(0);
        }
        return mService.getDevicesMatchingConnectionStates(
              new int[] {BluetoothProfile.STATE_CONNECTED,
                         BluetoothProfile.STATE_CONNECTING,
@@ -207,7 +205,7 @@ final class SapProfile implements LocalBluetoothProfile {
    }

    protected void finalize() {
        if (V) Log.d(TAG, "finalize()");
        Log.d(TAG, "finalize()");
        if (mService != null) {
            try {
                BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.SAP,
+93 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.settingslib.bluetooth;

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

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSap;
import android.bluetooth.BluetoothProfile;
import android.content.Context;

import com.android.settingslib.SettingsLibRobolectricTestRunner;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;

@RunWith(SettingsLibRobolectricTestRunner.class)
public class SapProfileTest {

    @Mock
    private LocalBluetoothAdapter mAdapter;
    @Mock
    private CachedBluetoothDeviceManager mDeviceManager;
    @Mock
    private LocalBluetoothProfileManager mProfileManager;
    @Mock
    private BluetoothSap mService;
    @Mock
    private CachedBluetoothDevice mCachedBluetoothDevice;
    @Mock
    private BluetoothDevice mBluetoothDevice;
    private BluetoothProfile.ServiceListener mServiceListener;
    private SapProfile mProfile;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        doAnswer((invocation) -> {
            mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1];
            return null;
        }).when(mAdapter).getProfileProxy(any(Context.class),
                any(BluetoothProfile.ServiceListener.class), eq(BluetoothProfile.SAP));

        mProfile = new SapProfile(RuntimeEnvironment.application, mAdapter,
                mDeviceManager, mProfileManager);
        mServiceListener.onServiceConnected(BluetoothProfile.SAP, mService);
    }

    @Test
    public void connect_shouldConnectBluetoothSap() {
        mProfile.connect(mBluetoothDevice);
        verify(mService).connect(mBluetoothDevice);
    }

    @Test
    public void disconnect_shouldDisconnectBluetoothSap() {
        mProfile.disconnect(mBluetoothDevice);
        verify(mService).disconnect(mBluetoothDevice);
    }

    @Test
    public void getConnectionStatus_shouldReturnConnectionState() {
        when(mService.getConnectionState(mBluetoothDevice)).
                thenReturn(BluetoothProfile.STATE_CONNECTED);
        assertThat(mProfile.getConnectionStatus(mBluetoothDevice)).
                isEqualTo(BluetoothProfile.STATE_CONNECTED);
    }
}
 No newline at end of file