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

Commit 494c6ce9 authored by wescande's avatar wescande Committed by Automerger Merge Worker
Browse files

Add getActiveDevices api am: 63628115

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/services/Telecomm/+/15853737

Change-Id: Id0e70d53418149032e5a01d52e15991de13fcde5
parents 1791fe75 63628115
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