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

Commit 7478a78d authored by xiaotonj's avatar xiaotonj Committed by Xiaotong Jia
Browse files

Handle broadcast from bluetooth stack in CallAudioRouteController

Bug: 306395598
Test: atest CallAudioRouteControllerTest
Change-Id: I91f90c31ba8a2af225f78d619217d5969c13768a
parent 2a733157
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@
    <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/>
    <uses-permission android:name="android.permission.ACCESS_LAST_KNOWN_CELL_ID"/>
    <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING" />

    <permission android:name="android.permission.BROADCAST_CALLLOG_INFO"
         android:label="Broadcast the call type/duration information"
+285 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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 static com.android.server.telecom.CallAudioRouteAdapter.BT_AUDIO_CONNECTED;
import static com.android.server.telecom.CallAudioRouteAdapter.BT_AUDIO_DISCONNECTED;
import static com.android.server.telecom.CallAudioRouteAdapter.PENDING_ROUTE_FAILED;
import static com.android.server.telecom.CallAudioRouteAdapter.SPEAKER_OFF;
import static com.android.server.telecom.CallAudioRouteAdapter.SPEAKER_ON;

import android.annotation.IntDef;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.telecom.Log;

import com.android.internal.annotations.VisibleForTesting;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class AudioRoute {
    public static class Factory {
        private final ScheduledExecutorService mScheduledExecutorService =
                new ScheduledThreadPoolExecutor(1);
        private final CompletableFuture<AudioRoute> mAudioRouteFuture = new CompletableFuture<>();
        public AudioRoute create(@AudioRouteType int type, String bluetoothAddress,
                                 AudioManager audioManager) throws RuntimeException {
            createRetry(type, bluetoothAddress, audioManager, MAX_CONNECTION_RETRIES);
            try {
                return mAudioRouteFuture.get();
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException("Error when creating requested audio route");
            }
        }
        private void createRetry(@AudioRouteType int type, String bluetoothAddress,
                                       AudioManager audioManager, int retryCount) {
            if (retryCount == 0) {
                mAudioRouteFuture.complete(null);
            }

            Log.i(this, "creating AudioRoute with type %s and address %s, retry count %d",
                    DEVICE_TYPE_STRINGS.get(type), bluetoothAddress, retryCount);
            AudioDeviceInfo routeInfo = null;
            List<AudioDeviceInfo> infos = audioManager.getAvailableCommunicationDevices();
            List<Integer> possibleInfoTypes = AUDIO_ROUTE_TYPE_TO_DEVICE_INFO_TYPE.get(type);
            for (AudioDeviceInfo info : infos) {
                Log.i(this, "type: " + info.getType());
                if (possibleInfoTypes != null && possibleInfoTypes.contains(info.getType())) {
                    if (BT_AUDIO_ROUTE_TYPES.contains(type)) {
                        if (bluetoothAddress.equals(info.getAddress())) {
                            routeInfo = info;
                            break;
                        }
                    } else {
                        routeInfo = info;
                        break;
                    }
                }
            }
            if (routeInfo == null) {
                CompletableFuture<Boolean> future = new CompletableFuture<>();
                mScheduledExecutorService.schedule(new Runnable() {
                    @Override
                    public void run() {
                        createRetry(type, bluetoothAddress, audioManager, retryCount - 1);
                    }
                }, RETRY_TIME_DELAY, TimeUnit.MILLISECONDS);
            } else {
                mAudioRouteFuture.complete(new AudioRoute(type, bluetoothAddress, routeInfo));
            }
        }
    }

    private static final long RETRY_TIME_DELAY = 500L;
    private static final int MAX_CONNECTION_RETRIES = 2;
    public static final int TYPE_INVALID = 0;
    public static final int TYPE_EARPIECE = 1;
    public static final int TYPE_WIRED = 2;
    public static final int TYPE_SPEAKER = 3;
    public static final int TYPE_DOCK = 4;
    public static final int TYPE_BLUETOOTH_SCO = 5;
    public static final int TYPE_BLUETOOTH_HA = 6;
    public static final int TYPE_BLUETOOTH_LE = 7;
    @IntDef(prefix = "TYPE", value = {
            TYPE_INVALID,
            TYPE_EARPIECE,
            TYPE_WIRED,
            TYPE_SPEAKER,
            TYPE_DOCK,
            TYPE_BLUETOOTH_SCO,
            TYPE_BLUETOOTH_HA,
            TYPE_BLUETOOTH_LE
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface AudioRouteType {}

    private @AudioRouteType int mAudioRouteType;
    private String mBluetoothAddress;
    private AudioDeviceInfo mInfo;
    public static final Set<Integer> BT_AUDIO_DEVICE_INFO_TYPES = Set.of(
            AudioDeviceInfo.TYPE_BLE_HEADSET,
            AudioDeviceInfo.TYPE_BLE_SPEAKER,
            AudioDeviceInfo.TYPE_BLE_BROADCAST,
            AudioDeviceInfo.TYPE_HEARING_AID,
            AudioDeviceInfo.TYPE_BLUETOOTH_SCO
    );

    public static final Set<Integer> BT_AUDIO_ROUTE_TYPES = Set.of(
            AudioRoute.TYPE_BLUETOOTH_SCO,
            AudioRoute.TYPE_BLUETOOTH_HA,
            AudioRoute.TYPE_BLUETOOTH_LE
    );

    public static final HashMap<Integer, String> DEVICE_TYPE_STRINGS;
    static {
        DEVICE_TYPE_STRINGS = new HashMap<>();
        DEVICE_TYPE_STRINGS.put(TYPE_EARPIECE, "TYPE_EARPIECE");
        DEVICE_TYPE_STRINGS.put(TYPE_WIRED, "TYPE_WIRED_HEADSET");
        DEVICE_TYPE_STRINGS.put(TYPE_SPEAKER, "TYPE_SPEAKER");
        DEVICE_TYPE_STRINGS.put(TYPE_DOCK, "TYPE_DOCK");
        DEVICE_TYPE_STRINGS.put(TYPE_BLUETOOTH_SCO, "TYPE_BLUETOOTH_SCO");
        DEVICE_TYPE_STRINGS.put(TYPE_BLUETOOTH_HA, "TYPE_BLUETOOTH_HA");
        DEVICE_TYPE_STRINGS.put(TYPE_BLUETOOTH_LE, "TYPE_BLUETOOTH_LE");
    }

    public static final HashMap<Integer, Integer> DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE;
    static {
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE = new HashMap<>();
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_BUILTIN_EARPIECE,
                TYPE_EARPIECE);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, TYPE_SPEAKER);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_WIRED_HEADSET, TYPE_WIRED);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_WIRED_HEADPHONES, TYPE_WIRED);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_BLUETOOTH_SCO,
                TYPE_BLUETOOTH_SCO);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_USB_DEVICE, TYPE_WIRED);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_USB_ACCESSORY, TYPE_WIRED);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_DOCK, TYPE_DOCK);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_USB_HEADSET, TYPE_WIRED);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_HEARING_AID,
                TYPE_BLUETOOTH_HA);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_BLE_HEADSET,
                TYPE_BLUETOOTH_LE);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_BLE_SPEAKER,
                TYPE_BLUETOOTH_LE);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_BLE_BROADCAST,
                TYPE_BLUETOOTH_LE);
        DEVICE_INFO_TYPETO_AUDIO_ROUTE_TYPE.put(AudioDeviceInfo.TYPE_DOCK_ANALOG, TYPE_DOCK);
    }

    private static final HashMap<Integer, List<Integer>> AUDIO_ROUTE_TYPE_TO_DEVICE_INFO_TYPE;
    static {
        AUDIO_ROUTE_TYPE_TO_DEVICE_INFO_TYPE = new HashMap<>();
        List<Integer> earpieceDeviceInfoTypes = new ArrayList<>();
        earpieceDeviceInfoTypes.add(AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);
        AUDIO_ROUTE_TYPE_TO_DEVICE_INFO_TYPE.put(TYPE_EARPIECE, earpieceDeviceInfoTypes);

        List<Integer> wiredDeviceInfoTypes = new ArrayList<>();
        wiredDeviceInfoTypes.add(AudioDeviceInfo.TYPE_WIRED_HEADSET);
        wiredDeviceInfoTypes.add(AudioDeviceInfo.TYPE_WIRED_HEADPHONES);
        wiredDeviceInfoTypes.add(AudioDeviceInfo.TYPE_USB_DEVICE);
        wiredDeviceInfoTypes.add(AudioDeviceInfo.TYPE_USB_ACCESSORY);
        wiredDeviceInfoTypes.add(AudioDeviceInfo.TYPE_USB_HEADSET);
        AUDIO_ROUTE_TYPE_TO_DEVICE_INFO_TYPE.put(TYPE_WIRED, wiredDeviceInfoTypes);

        List<Integer> speakerDeviceInfoTypes = new ArrayList<>();
        speakerDeviceInfoTypes.add(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
        AUDIO_ROUTE_TYPE_TO_DEVICE_INFO_TYPE.put(TYPE_SPEAKER, speakerDeviceInfoTypes);

        List<Integer> dockDeviceInfoTypes = new ArrayList<>();
        dockDeviceInfoTypes.add(AudioDeviceInfo.TYPE_DOCK);
        dockDeviceInfoTypes.add(AudioDeviceInfo.TYPE_DOCK_ANALOG);
        AUDIO_ROUTE_TYPE_TO_DEVICE_INFO_TYPE.put(TYPE_DOCK, dockDeviceInfoTypes);

        List<Integer> bluetoothScoDeviceInfoTypes = new ArrayList<>();
        bluetoothScoDeviceInfoTypes.add(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP);
        bluetoothScoDeviceInfoTypes.add(AudioDeviceInfo.TYPE_BLUETOOTH_SCO);
        AUDIO_ROUTE_TYPE_TO_DEVICE_INFO_TYPE.put(TYPE_BLUETOOTH_SCO, bluetoothScoDeviceInfoTypes);

        List<Integer> bluetoothHearingAidDeviceInfoTypes = new ArrayList<>();
        bluetoothHearingAidDeviceInfoTypes.add(AudioDeviceInfo.TYPE_HEARING_AID);
        AUDIO_ROUTE_TYPE_TO_DEVICE_INFO_TYPE.put(TYPE_BLUETOOTH_HA,
                bluetoothHearingAidDeviceInfoTypes);

        List<Integer> bluetoothLeDeviceInfoTypes = new ArrayList<>();
        bluetoothLeDeviceInfoTypes.add(AudioDeviceInfo.TYPE_BLE_HEADSET);
        bluetoothLeDeviceInfoTypes.add(AudioDeviceInfo.TYPE_BLE_SPEAKER);
        bluetoothLeDeviceInfoTypes.add(AudioDeviceInfo.TYPE_BLE_BROADCAST);
        AUDIO_ROUTE_TYPE_TO_DEVICE_INFO_TYPE.put(TYPE_BLUETOOTH_LE, bluetoothLeDeviceInfoTypes);
    }

    int getType() {
        return mAudioRouteType;
    }

    String getBluetoothAddress() {
        return mBluetoothAddress;
    }

    // Invoked when entered pending route whose dest route is this route
    void onDestRouteAsPendingRoute(boolean active, PendingAudioRoute pendingAudioRoute,
                                   AudioManager audioManager) {
        if (pendingAudioRoute.isActive() && !active) {
            audioManager.clearCommunicationDevice();
        } else if (active) {
            if (mAudioRouteType == TYPE_BLUETOOTH_SCO) {
                pendingAudioRoute.addMessage(BT_AUDIO_CONNECTED);
            } else if (mAudioRouteType == TYPE_SPEAKER) {
                pendingAudioRoute.addMessage(SPEAKER_ON);
            }
            if (!audioManager.setCommunicationDevice(mInfo)) {
                pendingAudioRoute.onMessageReceived(PENDING_ROUTE_FAILED);
            }
        }
    }

    void onOrigRouteAsPendingRoute(boolean active, PendingAudioRoute pendingAudioRoute,
                                   AudioManager audioManager) {
        if (active) {
            if (mAudioRouteType == TYPE_BLUETOOTH_SCO) {
                pendingAudioRoute.addMessage(BT_AUDIO_DISCONNECTED);
            } else if (mAudioRouteType == TYPE_SPEAKER) {
                pendingAudioRoute.addMessage(SPEAKER_OFF);
            }
        }
    }

    @VisibleForTesting
    public AudioRoute(@AudioRouteType int type, String bluetoothAddress, AudioDeviceInfo info) {
        mAudioRouteType = type;
        mBluetoothAddress = bluetoothAddress;
        mInfo = info;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof AudioRoute otherRoute)) {
            return false;
        }
        if (mAudioRouteType != otherRoute.getType()) {
            return false;
        }
        return !BT_AUDIO_ROUTE_TYPES.contains(mAudioRouteType) || mBluetoothAddress.equals(
                otherRoute.getBluetoothAddress());
    }

    @Override
    public int hashCode() {
        return Objects.hash(mAudioRouteType, mBluetoothAddress);
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + "[Type=" + DEVICE_TYPE_STRINGS.get(mAudioRouteType)
                + ", Address=" + ((mBluetoothAddress != null) ? mBluetoothAddress : "invalid")
                + "]";
    }
}
+4 −9
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.telecom;

import static com.android.server.telecom.AudioRoute.BT_AUDIO_DEVICE_INFO_TYPES;

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.media.AudioDeviceInfo;
@@ -28,7 +30,6 @@ import com.android.server.telecom.flags.Flags;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Semaphore;

/**
@@ -41,12 +42,6 @@ public class CallAudioCommunicationDeviceTracker {

    // Use -1 indicates device is not set for any communication use case
    private static final int sAUDIO_DEVICE_TYPE_INVALID = -1;
    // Possible bluetooth audio device types
    private static final Set<Integer> sBT_AUDIO_DEVICE_TYPES = Set.of(
            AudioDeviceInfo.TYPE_BLE_HEADSET,
            AudioDeviceInfo.TYPE_HEARING_AID,
            AudioDeviceInfo.TYPE_BLUETOOTH_SCO
    );
    private AudioManager mAudioManager;
    private BluetoothRouteManager mBluetoothRouteManager;
    private int mAudioDeviceType = sAUDIO_DEVICE_TYPE_INVALID;
@@ -101,7 +96,7 @@ public class CallAudioCommunicationDeviceTracker {
            mLock.tryAcquire();
        }
        // There is only one audio device type associated with each type of BT device.
        boolean isBtDevice = sBT_AUDIO_DEVICE_TYPES.contains(audioDeviceType);
        boolean isBtDevice = BT_AUDIO_DEVICE_INFO_TYPES.contains(audioDeviceType);
        Log.i(this, "setCommunicationDevice: type = %s, isBtDevice = %s, btDevice = %s",
                audioDeviceType, isBtDevice, btDevice);

@@ -182,7 +177,7 @@ public class CallAudioCommunicationDeviceTracker {
            mLock.tryAcquire();
        }
        // There is only one audio device type associated with each type of BT device.
        boolean isBtDevice = sBT_AUDIO_DEVICE_TYPES.contains(audioDeviceType);
        boolean isBtDevice = BT_AUDIO_DEVICE_INFO_TYPES.contains(audioDeviceType);
        Log.i(this, "clearCommunicationDevice: type = %s, isBtDevice = %s",
                audioDeviceType, isBtDevice);

+116 −0
Original line number Diff line number Diff line
package com.android.server.telecom;

import android.bluetooth.BluetoothDevice;
import android.os.Handler;
import android.telecom.CallAudioState;
import android.util.SparseArray;

import com.android.internal.util.IndentingPrintWriter;

public interface CallAudioRouteAdapter {
    /** Valid values for msg.what */
    int CONNECT_WIRED_HEADSET = 1;
    int DISCONNECT_WIRED_HEADSET = 2;
    int CONNECT_DOCK = 5;
    int DISCONNECT_DOCK = 6;
    int BLUETOOTH_DEVICE_LIST_CHANGED = 7;
    int BT_ACTIVE_DEVICE_PRESENT = 8;
    int BT_ACTIVE_DEVICE_GONE = 9;
    int BT_DEVICE_ADDED = 10;
    int BT_DEVICE_REMOVED = 11;

    int SWITCH_EARPIECE = 1001;
    int SWITCH_BLUETOOTH = 1002;
    int SWITCH_HEADSET = 1003;
    int SWITCH_SPEAKER = 1004;
    // Wired headset, earpiece, or speakerphone, in that order of precedence.
    int SWITCH_BASELINE_ROUTE = 1005;

    // Messages denoting that the speakerphone was turned on/off. Used to update state when we
    // weren't the ones who turned it on/off
    int SPEAKER_ON = 1006;
    int SPEAKER_OFF = 1007;

    // Messages denoting that the streaming route switch request was sent.
    int STREAMING_FORCE_ENABLED = 1008;
    int STREAMING_FORCE_DISABLED = 1009;

    int USER_SWITCH_EARPIECE = 1101;
    int USER_SWITCH_BLUETOOTH = 1102;
    int USER_SWITCH_HEADSET = 1103;
    int USER_SWITCH_SPEAKER = 1104;
    int USER_SWITCH_BASELINE_ROUTE = 1105;

    int UPDATE_SYSTEM_AUDIO_ROUTE = 1201;

    // These three messages indicate state changes that come from BluetoothRouteManager.
    // They may be triggered by the BT stack doing something on its own or they may be sent after
    // we request that the BT stack do something. Any logic for these messages should take into
    // account the possibility that the event indicated has already been processed (i.e. handling
    // should be idempotent).
    int BT_AUDIO_DISCONNECTED = 1301;
    int BT_AUDIO_CONNECTED = 1302;
    int BT_AUDIO_PENDING = 1303;

    int MUTE_ON = 3001;
    int MUTE_OFF = 3002;
    int TOGGLE_MUTE = 3003;
    int MUTE_EXTERNALLY_CHANGED = 3004;

    int SWITCH_FOCUS = 4001;

    // Used in testing to execute verifications. Not compatible with subsessions.
    int RUN_RUNNABLE = 9001;

    // Used for PendingAudioRoute to notify audio switch success
    int EXIT_PENDING_ROUTE = 10001;
    // Used for PendingAudioRoute to notify audio switch timeout
    int PENDING_ROUTE_TIMEOUT = 10002;
    // Used for PendingAudioRoute to notify audio switch failed
    int PENDING_ROUTE_FAILED = 10003;

    /** Valid values for mAudioFocusType */
    int NO_FOCUS = 1;
    int ACTIVE_FOCUS = 2;
    int RINGING_FOCUS = 3;

    /** Valid arg for BLUETOOTH_DEVICE_LIST_CHANGED */
    int DEVICE_CONNECTED = 1;
    int DEVICE_DISCONNECTED = 2;

    SparseArray<String> MESSAGE_CODE_TO_NAME = new SparseArray<String>() {{
        put(CONNECT_WIRED_HEADSET, "CONNECT_WIRED_HEADSET");
        put(DISCONNECT_WIRED_HEADSET, "DISCONNECT_WIRED_HEADSET");
        put(CONNECT_DOCK, "CONNECT_DOCK");
        put(DISCONNECT_DOCK, "DISCONNECT_DOCK");
        put(BLUETOOTH_DEVICE_LIST_CHANGED, "BLUETOOTH_DEVICE_LIST_CHANGED");
        put(BT_ACTIVE_DEVICE_PRESENT, "BT_ACTIVE_DEVICE_PRESENT");
        put(BT_ACTIVE_DEVICE_GONE, "BT_ACTIVE_DEVICE_GONE");
        put(BT_DEVICE_ADDED, "BT_DEVICE_ADDED");
        put(BT_DEVICE_REMOVED, "BT_DEVICE_REMOVED");

        put(SWITCH_EARPIECE, "SWITCH_EARPIECE");
        put(SWITCH_BLUETOOTH, "SWITCH_BLUETOOTH");
        put(SWITCH_HEADSET, "SWITCH_HEADSET");
        put(SWITCH_SPEAKER, "SWITCH_SPEAKER");
        put(SWITCH_BASELINE_ROUTE, "SWITCH_BASELINE_ROUTE");
        put(SPEAKER_ON, "SPEAKER_ON");
        put(SPEAKER_OFF, "SPEAKER_OFF");

        put(USER_SWITCH_EARPIECE, "USER_SWITCH_EARPIECE");
        put(USER_SWITCH_BLUETOOTH, "USER_SWITCH_BLUETOOTH");
        put(USER_SWITCH_HEADSET, "USER_SWITCH_HEADSET");
        put(USER_SWITCH_SPEAKER, "USER_SWITCH_SPEAKER");
        put(USER_SWITCH_BASELINE_ROUTE, "USER_SWITCH_BASELINE_ROUTE");

        put(UPDATE_SYSTEM_AUDIO_ROUTE, "UPDATE_SYSTEM_AUDIO_ROUTE");

        put(BT_AUDIO_DISCONNECTED, "BT_AUDIO_DISCONNECTED");
        put(BT_AUDIO_CONNECTED, "BT_AUDIO_CONNECTED");
        put(BT_AUDIO_PENDING, "BT_AUDIO_PENDING");

        put(MUTE_ON, "MUTE_ON");
        put(MUTE_OFF, "MUTE_OFF");
        put(TOGGLE_MUTE, "TOGGLE_MUTE");
        put(MUTE_EXTERNALLY_CHANGED, "MUTE_EXTERNALLY_CHANGED");

        put(SWITCH_FOCUS, "SWITCH_FOCUS");

        put(RUN_RUNNABLE, "RUN_RUNNABLE");

        put(EXIT_PENDING_ROUTE, "EXIT_PENDING_ROUTE");
    }};

    void initialize();
    void sendMessageWithSessionInfo(int message);
    void sendMessageWithSessionInfo(int message, int arg);
    void sendMessageWithSessionInfo(int message, int arg, String data);
    void sendMessageWithSessionInfo(int message, int arg, BluetoothDevice bluetoothDevice);
    void sendMessage(int message, Runnable r);
    void setCallAudioManager(CallAudioManager callAudioManager);
    CallAudioState getCurrentCallAudioState();
+472 −6

File changed.

Preview size limit exceeded, changes collapsed.

Loading