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

Commit 63628115 authored by wescande's avatar wescande Committed by William Escande
Browse files

Add getActiveDevices api

replace calls to hidden API by the systemApi.
Delete unecessary proxy around HeadsetService and Adapter

Bug: 195149213
Test: atest TelecomUnitTests
Tag: #feature
AOSP: aosp/1798127
Change-Id: Icc0b695c320d81ca5c0bfbaf7c1fac9a45f9699c
parent a95672ba
Loading
Loading
Loading
Loading
+0 −52
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.server.telecom;

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

/**
 * Proxy class used so that BluetoothAdapter can be mocked for testing.
 */
public class BluetoothAdapterProxy {
    private BluetoothAdapter mBluetoothAdapter;

    public BluetoothAdapterProxy() {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    }

    public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,
            int profile) {
        if (mBluetoothAdapter == null) {
            return false;
        }
        return mBluetoothAdapter.getProfileProxy(context, listener, profile);
    }

    public boolean setActiveDevice(BluetoothDevice device, int profiles) {
        if (mBluetoothAdapter == null) {
            return false;
        }
        if (device != null) {
            return mBluetoothAdapter.setActiveDevice(device, profiles);
        } else {
            return mBluetoothAdapter.removeActiveDevice(profiles);
        }
    }
}
+0 −74
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.server.telecom;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;

import java.util.List;

/**
 * A proxy class that facilitates testing of the BluetoothPhoneServiceImpl class.
 *
 * This is necessary due to the "final" attribute of the BluetoothHeadset class. In order to
 * test the correct functioning of the BluetoothPhoneServiceImpl class, the final class must be put
 * into a container that can be mocked correctly.
 */
public class BluetoothHeadsetProxy {

    private BluetoothHeadset mBluetoothHeadset;

    public BluetoothHeadsetProxy(BluetoothHeadset headset) {
        mBluetoothHeadset = headset;
    }

    public List<BluetoothDevice> getConnectedDevices() {
        return mBluetoothHeadset.getConnectedDevices();
    }

    public int getConnectionState(BluetoothDevice device) {
        return mBluetoothHeadset.getConnectionState(device);
    }

    public int getAudioState(BluetoothDevice device) {
        return mBluetoothHeadset.getAudioState(device);
    }

    public boolean connectAudio() {
        return mBluetoothHeadset.connectAudio();
    }

    public boolean setActiveDevice(BluetoothDevice device) {
        return mBluetoothHeadset.setActiveDevice(device);
    }

    public BluetoothDevice getActiveDevice() {
        return mBluetoothHeadset.getActiveDevice();
    }

    public boolean isAudioOn() {
        return mBluetoothHeadset.isAudioOn();
    }

    public boolean disconnectAudio() {
        return mBluetoothHeadset.disconnectAudio();
    }

    public boolean isInbandRingingEnabled() {
        return mBluetoothHeadset.isInbandRingingEnabled();
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter
import com.android.server.telecom.ui.ToastFactory;

import android.app.ActivityManager;
import android.bluetooth.BluetoothManager;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -232,7 +233,7 @@ public class TelecomSystem {
                        }
                    });
            BluetoothDeviceManager bluetoothDeviceManager = new BluetoothDeviceManager(mContext,
                    new BluetoothAdapterProxy());
                    new BluetoothManager(mContext).getAdapter());
            BluetoothRouteManager bluetoothRouteManager = new BluetoothRouteManager(mContext, mLock,
                    bluetoothDeviceManager, new Timeouts.Adapter());
            BluetoothStateReceiver bluetoothStateReceiver = new BluetoothStateReceiver(
+51 −57
Original line number Diff line number Diff line
@@ -26,8 +26,6 @@ import android.telecom.Log;
import android.util.LocalLog;

import com.android.internal.util.IndentingPrintWriter;
import com.android.server.telecom.BluetoothAdapterProxy;
import com.android.server.telecom.BluetoothHeadsetProxy;

import java.util.ArrayList;
import java.util.Collection;
@@ -48,13 +46,12 @@ public class BluetoothDeviceManager {
                        synchronized (mLock) {
                            String logString;
                            if (profile == BluetoothProfile.HEADSET) {
                                mBluetoothHeadsetService =
                                        new BluetoothHeadsetProxy((BluetoothHeadset) proxy);
                                logString = "Got BluetoothHeadset: " + mBluetoothHeadsetService;
                                mBluetoothHeadset = (BluetoothHeadset) proxy;
                                logString = "Got BluetoothHeadset: " + mBluetoothHeadset;
                            } else if (profile == BluetoothProfile.HEARING_AID) {
                                mBluetoothHearingAidService = (BluetoothHearingAid) proxy;
                                mBluetoothHearingAid = (BluetoothHearingAid) proxy;
                                logString = "Got BluetoothHearingAid: "
                                        + mBluetoothHearingAidService;
                                        + mBluetoothHearingAid;
                            } else {
                                logString = "Connected to non-requested bluetooth service." +
                                        " Not changing bluetooth headset.";
@@ -75,13 +72,13 @@ public class BluetoothDeviceManager {
                            LinkedHashMap<String, BluetoothDevice> lostServiceDevices;
                            String logString;
                            if (profile == BluetoothProfile.HEADSET) {
                                mBluetoothHeadsetService = null;
                                mBluetoothHeadset = null;
                                lostServiceDevices = mHfpDevicesByAddress;
                                mBluetoothRouteManager.onActiveDeviceChanged(null, false);
                                logString = "Lost BluetoothHeadset service. " +
                                        "Removing all tracked devices";
                            } else if (profile == BluetoothProfile.HEARING_AID) {
                                mBluetoothHearingAidService = null;
                                mBluetoothHearingAid = null;
                                logString = "Lost BluetoothHearingAid service. " +
                                        "Removing all tracked devices.";
                                lostServiceDevices = mHearingAidDevicesByAddress;
@@ -117,14 +114,14 @@ public class BluetoothDeviceManager {
    private final Object mLock = new Object();

    private BluetoothRouteManager mBluetoothRouteManager;
    private BluetoothHeadsetProxy mBluetoothHeadsetService;
    private BluetoothHearingAid mBluetoothHearingAidService;
    private BluetoothHeadset mBluetoothHeadset;
    private BluetoothHearingAid mBluetoothHearingAid;
    private BluetoothDevice mBluetoothHearingAidActiveDeviceCache;
    private BluetoothAdapterProxy mBluetoothAdapterProxy;
    private BluetoothAdapter mBluetoothAdapter;

    public BluetoothDeviceManager(Context context, BluetoothAdapterProxy bluetoothAdapter) {
    public BluetoothDeviceManager(Context context, BluetoothAdapter bluetoothAdapter) {
        if (bluetoothAdapter != null) {
            mBluetoothAdapterProxy = bluetoothAdapter;
            mBluetoothAdapter = bluetoothAdapter;
            bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
                    BluetoothProfile.HEADSET);
            bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
@@ -160,15 +157,14 @@ public class BluetoothDeviceManager {
        Set<Long> seenHiSyncIds = new LinkedHashSet<>();
        // Add the left-most active device to the seen list so that we match up with the list
        // generated in BluetoothRouteManager.
        if (mBluetoothHearingAidService != null) {
            for (BluetoothDevice device : mBluetoothHearingAidService.getActiveDevices()) {
        for (BluetoothDevice device : mBluetoothAdapter.getActiveDevices(
                    BluetoothProfile.HEARING_AID)) {
            if (device != null) {
                result.add(device);
                seenHiSyncIds.add(mHearingAidDeviceSyncIds.getOrDefault(device, -1L));
                break;
            }
        }
        }
        synchronized (mLock) {
            for (BluetoothDevice d : mHearingAidDevicesByAddress.values()) {
                long hiSyncId = mHearingAidDeviceSyncIds.getOrDefault(d, -1L);
@@ -182,20 +178,24 @@ public class BluetoothDeviceManager {
        return Collections.unmodifiableCollection(result);
    }

    public BluetoothHeadsetProxy getHeadsetService() {
        return mBluetoothHeadsetService;
    public BluetoothHeadset getBluetoothHeadset() {
        return mBluetoothHeadset;
    }

    public BluetoothAdapter getBluetoothAdapter() {
        return mBluetoothAdapter;
    }

    public BluetoothHearingAid getHearingAidService() {
        return mBluetoothHearingAidService;
    public BluetoothHearingAid getBluetoothHearingAid() {
        return mBluetoothHearingAid;
    }

    public void setHeadsetServiceForTesting(BluetoothHeadsetProxy bluetoothHeadset) {
        mBluetoothHeadsetService = bluetoothHeadset;
    public void setHeadsetServiceForTesting(BluetoothHeadset bluetoothHeadset) {
        mBluetoothHeadset = bluetoothHeadset;
    }

    public void setHearingAidServiceForTesting(BluetoothHearingAid bluetoothHearingAid) {
        mBluetoothHearingAidService = bluetoothHearingAid;
        mBluetoothHearingAid = bluetoothHearingAid;
    }

    void onDeviceConnected(BluetoothDevice device, boolean isHearingAid) {
@@ -204,15 +204,15 @@ public class BluetoothDeviceManager {
        synchronized (mLock) {
            LinkedHashMap<String, BluetoothDevice> targetDeviceMap;
            if (isHearingAid) {
                if (mBluetoothHearingAidService == null) {
                if (mBluetoothHearingAid == null) {
                    Log.w(this, "Hearing aid service null when receiving device added broadcast");
                    return;
                }
                long hiSyncId = mBluetoothHearingAidService.getHiSyncId(device);
                long hiSyncId = mBluetoothHearingAid.getHiSyncId(device);
                mHearingAidDeviceSyncIds.put(device, hiSyncId);
                targetDeviceMap = mHearingAidDevicesByAddress;
            } else {
                if (mBluetoothHeadsetService == null) {
                if (mBluetoothHeadset == null) {
                    Log.w(this, "Headset service null when receiving device added broadcast");
                    return;
                }
@@ -244,24 +244,20 @@ public class BluetoothDeviceManager {
    }

    public void disconnectAudio() {
        if (mBluetoothHearingAidService == null) {
            Log.w(this, "Trying to disconnect audio but no hearing aid service exists");
        } else {
            for (BluetoothDevice device : mBluetoothHearingAidService.getActiveDevices()) {
        for (BluetoothDevice device: mBluetoothAdapter.getActiveDevices(
                    BluetoothProfile.HEARING_AID)) {
            if (device != null) {
                    mBluetoothAdapterProxy.setActiveDevice(null,
                        BluetoothAdapter.ACTIVE_DEVICE_ALL);
                }
                mBluetoothAdapter.setActiveDevice(null, BluetoothAdapter.ACTIVE_DEVICE_ALL);
            }
        }
        disconnectSco();
    }

    public void disconnectSco() {
        if (mBluetoothHeadsetService == null) {
        if (mBluetoothHeadset == null) {
            Log.w(this, "Trying to disconnect audio but no headset service exists.");
        } else {
            mBluetoothHeadsetService.disconnectAudio();
            mBluetoothHeadset.disconnectAudio();
        }
    }

@@ -269,27 +265,27 @@ public class BluetoothDeviceManager {
    // or a HFP device, and using the proper BT API.
    public boolean connectAudio(String address) {
        if (mHearingAidDevicesByAddress.containsKey(address)) {
            if (mBluetoothHearingAidService == null) {
            if (mBluetoothHearingAid == null) {
                Log.w(this, "Attempting to turn on audio when the hearing aid service is null");
                return false;
            }
            return mBluetoothAdapterProxy.setActiveDevice(
            return mBluetoothAdapter.setActiveDevice(
                    mHearingAidDevicesByAddress.get(address),
                    BluetoothAdapter.ACTIVE_DEVICE_ALL);
        } else if (mHfpDevicesByAddress.containsKey(address)) {
            BluetoothDevice device = mHfpDevicesByAddress.get(address);
            if (mBluetoothHeadsetService == null) {
            if (mBluetoothHeadset == null) {
                Log.w(this, "Attempting to turn on audio when the headset service is null");
                return false;
            }
            boolean success = mBluetoothAdapterProxy.setActiveDevice(device,
            boolean success = mBluetoothAdapter.setActiveDevice(device,
                BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL);
            if (!success) {
                Log.w(this, "Couldn't set active device to %s", address);
                return false;
            }
            if (!mBluetoothHeadsetService.isAudioOn()) {
                return mBluetoothHeadsetService.connectAudio();
            if (!mBluetoothHeadset.isAudioOn()) {
                return mBluetoothHeadset.connectAudio();
            }
            return true;
        } else {
@@ -299,19 +295,17 @@ public class BluetoothDeviceManager {
    }

    public void cacheHearingAidDevice() {
        if (mBluetoothHearingAidService != null) {
             for (BluetoothDevice device : mBluetoothHearingAidService.getActiveDevices()) {
        for (BluetoothDevice device : mBluetoothAdapter.getActiveDevices(
                    BluetoothProfile.HEARING_AID)) {
            if (device != null) {
                mBluetoothHearingAidActiveDeviceCache = device;
            }
        }
    }
    }

    public void restoreHearingAidDevice() {
        if (mBluetoothHearingAidActiveDeviceCache != null && mBluetoothHearingAidService != null) {
            mBluetoothAdapterProxy.setActiveDevice(
                mBluetoothHearingAidActiveDeviceCache,
        if (mBluetoothHearingAidActiveDeviceCache != null) {
            mBluetoothAdapter.setActiveDevice(mBluetoothHearingAidActiveDeviceCache,
                    BluetoothAdapter.ACTIVE_DEVICE_ALL);
            mBluetoothHearingAidActiveDeviceCache = null;
        }
+17 −6
Original line number Diff line number Diff line
@@ -16,9 +16,11 @@

package com.android.server.telecom.bluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.os.Message;
import android.telecom.Log;
@@ -30,7 +32,6 @@ import com.android.internal.os.SomeArgs;
import com.android.internal.util.IState;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.server.telecom.BluetoothHeadsetProxy;
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.Timeouts;

@@ -701,19 +702,28 @@ public class BluetoothRouteManager extends StateMachine {
     */
    @VisibleForTesting
    public BluetoothDevice getBluetoothAudioConnectedDevice() {
        BluetoothHeadsetProxy bluetoothHeadset = mDeviceManager.getHeadsetService();
        BluetoothHearingAid bluetoothHearingAid = mDeviceManager.getHearingAidService();
        BluetoothAdapter bluetoothAdapter = mDeviceManager.getBluetoothAdapter();
        BluetoothHeadset bluetoothHeadset = mDeviceManager.getBluetoothHeadset();
        BluetoothHearingAid bluetoothHearingAid = mDeviceManager.getBluetoothHearingAid();

        BluetoothDevice hfpAudioOnDevice = null;
        BluetoothDevice hearingAidActiveDevice = null;

        if (bluetoothAdapter == null) {
            Log.i(this, "getBluetoothAudioConnectedDevice: no adapter available.");
            return null;
        }
        if (bluetoothHeadset == null && bluetoothHearingAid == null) {
            Log.i(this, "getBluetoothAudioConnectedDevice: no service available.");
            return null;
        }

        if (bluetoothHeadset != null) {
            hfpAudioOnDevice = bluetoothHeadset.getActiveDevice();
            for (BluetoothDevice device : bluetoothAdapter.getActiveDevices(
                        BluetoothProfile.HEADSET)) {
                hfpAudioOnDevice = device;
                break;
            }

            if (bluetoothHeadset.getAudioState(hfpAudioOnDevice)
                    == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
@@ -722,7 +732,8 @@ public class BluetoothRouteManager extends StateMachine {
        }

        if (bluetoothHearingAid != null) {
            for (BluetoothDevice device : bluetoothHearingAid.getActiveDevices()) {
            for (BluetoothDevice device : bluetoothAdapter.getActiveDevices(
                        BluetoothProfile.HEARING_AID)) {
                if (device != null) {
                    hearingAidActiveDevice = device;
                    break;
@@ -751,7 +762,7 @@ public class BluetoothRouteManager extends StateMachine {
     */
    @VisibleForTesting
    public boolean isInbandRingingEnabled() {
        BluetoothHeadsetProxy bluetoothHeadset = mDeviceManager.getHeadsetService();
        BluetoothHeadset bluetoothHeadset = mDeviceManager.getBluetoothHeadset();
        if (bluetoothHeadset == null) {
            Log.i(this, "isInbandRingingEnabled: no headset service available.");
            return false;
Loading