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

Commit dcc6879e authored by Sal Savage's avatar Sal Savage Committed by Gerrit Code Review
Browse files

Merge changes from topic "hfp-client-connection-service-package"

* changes:
  Replace BluetoothHeadsetClientCall with internal HfpClientCall
  Remove HFP Client Connection Service's usage of BluetoothHeadsetClient
  Have HfpClientConnectionService get updates directly from HFP service
  Move HFP Client Connection Service to the HFP Client package
parents 4fb4d45d f1e63c0b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -398,7 +398,7 @@
            </intent-filter>
        </service>
        <service android:process="@string/process"
             android:name=".hfpclient.connserv.HfpClientConnectionService"
             android:name=".hfpclient.HfpClientConnectionService"
             android:permission="android.permission.BIND_CONNECTION_SERVICE"
             android:enabled="@bool/hfp_client_connection_service_enabled"
             android:exported="true">
+2 −2
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.bluetooth.a2dpsink;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadsetClientCall;
import android.content.pm.PackageManager;
import android.media.AudioAttributes;
import android.media.AudioFocusRequest;
@@ -32,6 +31,7 @@ import android.util.Log;
import com.android.bluetooth.R;
import com.android.bluetooth.avrcpcontroller.BluetoothMediaBrowserService;
import com.android.bluetooth.hfpclient.HeadsetClientService;
import com.android.bluetooth.hfpclient.HfpClientCall;

import java.util.List;

@@ -372,7 +372,7 @@ public class A2dpSinkStreamHandler extends Handler {
        }
        HeadsetClientService headsetClientService = HeadsetClientService.getHeadsetClientService();
        if (targetDevice != null && headsetClientService != null) {
            List<BluetoothHeadsetClientCall> currentCalls =
            List<HfpClientCall> currentCalls =
                    headsetClientService.getCurrentCalls(targetDevice);
            if (currentCalls == null) return false;
            return currentCalls.size() > 0;
+44 −19
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.hfpclient.connserv.HfpClientConnectionService;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.SynchronousResultReceiver;
@@ -49,6 +48,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;

/**
@@ -244,6 +244,13 @@ public class HeadsetClientService extends ProfileService {
        }
    };

    private static BluetoothHeadsetClientCall toLegacyCall(HfpClientCall call) {
        if (call == null) return null;
        return new BluetoothHeadsetClientCall(call.getDevice(), call.getId(), call.getUUID(),
                call.getState(), call.getNumber(), call.isMultiParty(), call.isOutgoing(),
                call.isInBandRing());
    }

    /**
     * Handlers for incoming service calls
     */
@@ -579,7 +586,8 @@ public class HeadsetClientService extends ProfileService {
                HeadsetClientService service = getService(source);
                BluetoothHeadsetClientCall defaultValue = null;
                if (service != null) {
                    defaultValue = service.dial(device, number);
                    HfpClientCall call = service.dial(device, number);
                    defaultValue = toLegacyCall(call);
                }
                receiver.send(defaultValue);
            } catch (RuntimeException e) {
@@ -594,7 +602,10 @@ public class HeadsetClientService extends ProfileService {
                HeadsetClientService service = getService(source);
                List<BluetoothHeadsetClientCall> defaultValue = new ArrayList<>();
                if (service != null) {
                    defaultValue = service.getCurrentCalls(device);
                    List<HfpClientCall> calls = service.getCurrentCalls(device);
                    for (HfpClientCall call : calls) {
                        defaultValue.add(toLegacyCall(call));
                    }
                }
                receiver.send(defaultValue);
            } catch (RuntimeException e) {
@@ -669,7 +680,7 @@ public class HeadsetClientService extends ProfileService {
                HeadsetClientService service = getService(source);
                Bundle defaultValue = null;
                if (service != null) {
                    defaultValue = service.getCurrentAgFeatures(device);
                    defaultValue = service.getCurrentAgFeaturesBundle(device);
                }
                receiver.send(defaultValue);
            } catch (RuntimeException e) {
@@ -678,8 +689,6 @@ public class HeadsetClientService extends ProfileService {
        }
    }

    ;

    // API methods
    public static synchronized HeadsetClientService getHeadsetClientService() {
        if (sHeadsetClientService == null) {
@@ -903,7 +912,7 @@ public class HeadsetClientService extends ProfileService {
        return false;
    }

    boolean connectAudio(BluetoothDevice device) {
    public boolean connectAudio(BluetoothDevice device) {
        HeadsetClientStateMachine sm = getStateMachine(device);
        if (sm == null) {
            Log.e(TAG, "SM does not exist for device " + device);
@@ -920,7 +929,7 @@ public class HeadsetClientService extends ProfileService {
        return true;
    }

    boolean disconnectAudio(BluetoothDevice device) {
    public boolean disconnectAudio(BluetoothDevice device) {
        HeadsetClientStateMachine sm = getStateMachine(device);
        if (sm == null) {
            Log.e(TAG, "SM does not exist for device " + device);
@@ -934,7 +943,7 @@ public class HeadsetClientService extends ProfileService {
        return true;
    }

    boolean holdCall(BluetoothDevice device) {
    public boolean holdCall(BluetoothDevice device) {
        HeadsetClientStateMachine sm = getStateMachine(device);
        if (sm == null) {
            Log.e(TAG, "SM does not exist for device " + device);
@@ -951,7 +960,7 @@ public class HeadsetClientService extends ProfileService {
        return true;
    }

    boolean acceptCall(BluetoothDevice device, int flag) {
    public boolean acceptCall(BluetoothDevice device, int flag) {
        /* Phonecalls from a single device are supported, hang up any calls on the other phone */
        synchronized (mStateMachineMap) {
            for (Map.Entry<BluetoothDevice, HeadsetClientStateMachine> entry : mStateMachineMap
@@ -988,7 +997,7 @@ public class HeadsetClientService extends ProfileService {
        return true;
    }

    boolean rejectCall(BluetoothDevice device) {
    public boolean rejectCall(BluetoothDevice device) {
        HeadsetClientStateMachine sm = getStateMachine(device);
        if (sm == null) {
            Log.e(TAG, "SM does not exist for device " + device);
@@ -1006,7 +1015,7 @@ public class HeadsetClientService extends ProfileService {
        return true;
    }

    boolean terminateCall(BluetoothDevice device, UUID uuid) {
    public boolean terminateCall(BluetoothDevice device, UUID uuid) {
        HeadsetClientStateMachine sm = getStateMachine(device);
        if (sm == null) {
            Log.e(TAG, "SM does not exist for device " + device);
@@ -1025,7 +1034,7 @@ public class HeadsetClientService extends ProfileService {
        return true;
    }

    boolean enterPrivateMode(BluetoothDevice device, int index) {
    public boolean enterPrivateMode(BluetoothDevice device, int index) {
        HeadsetClientStateMachine sm = getStateMachine(device);
        if (sm == null) {
            Log.e(TAG, "SM does not exist for device " + device);
@@ -1044,7 +1053,7 @@ public class HeadsetClientService extends ProfileService {
        return true;
    }

    BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) {
    public HfpClientCall dial(BluetoothDevice device, String number) {
        HeadsetClientStateMachine sm = getStateMachine(device);
        if (sm == null) {
            Log.e(TAG, "SM does not exist for device " + device);
@@ -1057,9 +1066,9 @@ public class HeadsetClientService extends ProfileService {
            return null;
        }

        BluetoothHeadsetClientCall call = new BluetoothHeadsetClientCall(device,
        HfpClientCall call = new HfpClientCall(device,
                HeadsetClientStateMachine.HF_ORIGINATED_CALL_ID,
                BluetoothHeadsetClientCall.CALL_STATE_DIALING, number, false  /* multiparty */,
                HfpClientCall.CALL_STATE_DIALING, number, false  /* multiparty */,
                true  /* outgoing */, sm.getInBandRing());
        Message msg = sm.obtainMessage(HeadsetClientStateMachine.DIAL_NUMBER);
        msg.obj = call;
@@ -1089,7 +1098,7 @@ public class HeadsetClientService extends ProfileService {
        return false;
    }

    public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) {
    public List<HfpClientCall> getCurrentCalls(BluetoothDevice device) {
        HeadsetClientStateMachine sm = getStateMachine(device);
        if (sm == null) {
            Log.e(TAG, "SM does not exist for device " + device);
@@ -1153,7 +1162,20 @@ public class HeadsetClientService extends ProfileService {
        return sm.getCurrentAgEvents();
    }

    public Bundle getCurrentAgFeatures(BluetoothDevice device) {
    public Bundle getCurrentAgFeaturesBundle(BluetoothDevice device) {
        HeadsetClientStateMachine sm = getStateMachine(device);
        if (sm == null) {
            Log.e(TAG, "SM does not exist for device " + device);
            return null;
        }
        int connectionState = sm.getConnectionState(device);
        if (connectionState != BluetoothProfile.STATE_CONNECTED) {
            return null;
        }
        return sm.getCurrentAgFeaturesBundle();
    }

    public Set<Integer> getCurrentAgFeatures(BluetoothDevice device) {
        HeadsetClientStateMachine sm = getStateMachine(device);
        if (sm == null) {
            Log.e(TAG, "SM does not exist for device " + device);
@@ -1270,7 +1292,7 @@ public class HeadsetClientService extends ProfileService {
                    .entrySet()) {
                if (entry.getValue() != null) {
                    int audioState = entry.getValue().getAudioState(entry.getKey());
                    if (audioState == BluetoothHeadsetClient.STATE_AUDIO_CONNECTED) {
                    if (audioState == HeadsetClientHalConstants.AUDIO_STATE_CONNECTED) {
                        if (DBG) {
                            Log.d(TAG, "Device " + entry.getKey() + " audio state " + audioState
                                    + " Connected");
@@ -1292,6 +1314,9 @@ public class HeadsetClientService extends ProfileService {
                    sm.dump(sb);
                }
            }

            sb.append("\n");
            HfpClientConnectionService.dump(sb);
        }
    }

+105 −57

File changed.

Preview size limit exceeded, changes collapsed.

+0 −128
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.hfpclient.connserv;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadsetClient;
import android.bluetooth.BluetoothHeadsetClientCall;
import android.os.Bundle;

import com.android.internal.annotations.VisibleForTesting;

import java.util.List;

/**
 * A mockable proxy class that facilitates testing of the {@code hfpclient.connserv} package.
 *
 * <p>This is necessary due to the "final" attribute of the BluetoothHeadsetClient class.
 */
public class BluetoothHeadsetClientProxy {

    private final BluetoothHeadsetClient mBluetoothHeadsetClient;

    private BluetoothHeadsetClientProxy(BluetoothHeadsetClient bluetoothHeadsetClient) {
        mBluetoothHeadsetClient = bluetoothHeadsetClient;
    }

    public BluetoothHeadsetClient getProxiedBluetoothHeadsetClient() {
        return mBluetoothHeadsetClient;
    }

    /** @see BluetoothHeadsetClient#dial(BluetoothDevice, String) */
    public BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) {
        return mBluetoothHeadsetClient.dial(device, number);
    }

    /** @see BluetoothHeadsetClient#enterPrivateMode(BluetoothDevice, int) */
    public boolean enterPrivateMode(BluetoothDevice device, int index) {
        return mBluetoothHeadsetClient.enterPrivateMode(device, index);
    }

    /** @see BluetoothHeadsetClient#sendDTMF(BluetoothDevice, byte) */
    public boolean sendDTMF(BluetoothDevice device, byte code) {
        return mBluetoothHeadsetClient.sendDTMF(device, code);
    }

    /** @see BluetoothHeadsetClient#terminateCall(BluetoothDevice, BluetoothHeadsetClientCall) */
    public boolean terminateCall(BluetoothDevice device, BluetoothHeadsetClientCall call) {
        return mBluetoothHeadsetClient.terminateCall(device, call);
    }

    /** @see BluetoothHeadsetClient#holdCall(BluetoothDevice) */
    public boolean holdCall(BluetoothDevice device) {
        return mBluetoothHeadsetClient.holdCall(device);
    }

    /** @see BluetoothHeadsetClient#acceptCall(BluetoothDevice, int) */
    public boolean acceptCall(BluetoothDevice device, int flag) {
        return mBluetoothHeadsetClient.acceptCall(device, flag);
    }

    /** @see BluetoothHeadsetClient#rejectCall(BluetoothDevice) */
    public boolean rejectCall(BluetoothDevice device) {
        return mBluetoothHeadsetClient.rejectCall(device);
    }

    /** @see BluetoothHeadsetClient#connectAudio(BluetoothDevice) */
    public boolean connectAudio(BluetoothDevice device) {
        return mBluetoothHeadsetClient.connectAudio(device);
    }

    /** @see BluetoothHeadsetClient#disconnectAudio(BluetoothDevice) */
    public boolean disconnectAudio(BluetoothDevice device) {
        return mBluetoothHeadsetClient.disconnectAudio(device);
    }

    /** @see BluetoothHeadsetClient#getCurrentAgEvents(BluetoothDevice) */
    public Bundle getCurrentAgEvents(BluetoothDevice device) {
        return mBluetoothHeadsetClient.getCurrentAgEvents(device);
    }

    /** @see BluetoothHeadsetClient#getConnectedDevices() */
    public List<BluetoothDevice> getConnectedDevices() {
        return mBluetoothHeadsetClient.getConnectedDevices();
    }

    /** @see BluetoothHeadsetClient#getCurrentCalls(BluetoothDevice) */
    public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) {
        return mBluetoothHeadsetClient.getCurrentCalls(device);
    }

    /**
     * Factory class for {@link BluetoothHeadsetClientProxy}
     */
    public static class Factory {
        private static Factory sInstance = new Factory();

        @VisibleForTesting
        static void setInstance(Factory instance) {
            sInstance = instance;
        }

        /**
         * Returns an instance of {@link BluetoothHeadsetClientProxy}
         */
        public static BluetoothHeadsetClientProxy build(BluetoothHeadsetClient proxy) {
            return sInstance.buildInternal(proxy);
        }

        protected BluetoothHeadsetClientProxy buildInternal(BluetoothHeadsetClient proxy) {
            return  new BluetoothHeadsetClientProxy(proxy);
        }

    }
}
Loading