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

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

A2DP switch device refactor

Bluetooth mainline effort to reduce AudioManager API

Test: Manual
Tag: #refactor
Bug: 190422401
Fix: 197715842
Fix: 197932292
Merged-In: I65c6561969d443e80f0a49256770279cd0959352
Change-Id: I65c6561969d443e80f0a49256770279cd0959352
parent 8aa04b89
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ package android.media {
  public class AudioManager {
    method public void adjustStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
    method public void adjustSuggestedStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void handleBluetoothActiveDeviceChanged(@Nullable android.bluetooth.BluetoothDevice, @Nullable android.bluetooth.BluetoothDevice, @NonNull android.media.BtProfileConnectionInfo);
    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setA2dpSuspended(boolean);
    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setBluetoothHeadsetProperties(@NonNull String, boolean, boolean);
    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setHfpEnabled(boolean);
@@ -122,6 +123,19 @@ package android.media {
    field public static final int FLAG_FROM_KEY = 4096; // 0x1000
  }

  public final class BtProfileConnectionInfo implements android.os.Parcelable {
    method @NonNull public static android.media.BtProfileConnectionInfo a2dpInfo(boolean, int);
    method public int describeContents();
    method public boolean getIsLeOutput();
    method public int getProfile();
    method public boolean getSuppressNoisyIntent();
    method public int getVolume();
    method @NonNull public static android.media.BtProfileConnectionInfo hearingAidInfo(boolean);
    method @NonNull public static android.media.BtProfileConnectionInfo leAudio(boolean, boolean);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.media.BtProfileConnectionInfo> CREATOR;
  }

  public class MediaMetadataRetriever implements java.lang.AutoCloseable {
    field public static final int METADATA_KEY_VIDEO_CODEC_MIME_TYPE = 40; // 0x28
  }
+14 −102
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothCodecConfig;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
@@ -5797,111 +5796,24 @@ public class AudioManager {
    }

    /**
     * Indicate Hearing Aid connection state change and eventually suppress
     * the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent.
     * This operation is asynchronous but its execution will still be sequentially scheduled
     * relative to calls to {@link #setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
     * * BluetoothDevice, int, int, boolean, int)} and
     * and {@link #handleBluetoothA2dpDeviceConfigChange(BluetoothDevice)}.
     * @param device Bluetooth device connected/disconnected
     * @param state new connection state (BluetoothProfile.STATE_xxx)
     * @param musicDevice Default get system volume for the connecting device.
     * (either {@link android.bluetooth.BluetoothProfile.hearingaid} or
     * {@link android.bluetooth.BluetoothProfile.HEARING_AID})
     * @param suppressNoisyIntent if true the
     * {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be sent.
     * {@hide}
     */
    public void setBluetoothHearingAidDeviceConnectionState(
                BluetoothDevice device, int state, boolean suppressNoisyIntent,
                int musicDevice) {
        final IAudioService service = getService();
        try {
            service.setBluetoothHearingAidDeviceConnectionState(device,
                state, suppressNoisyIntent, musicDevice);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
    * Indicate Le Audio output device connection state change and eventually suppress
    * the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent.
    * @param device Bluetooth device connected/disconnected
    * @param state new connection state (BluetoothProfile.STATE_xxx)
    * @param suppressNoisyIntent if true the
    * {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be sent.
    * {@hide}
    */
    public void setBluetoothLeAudioOutDeviceConnectionState(BluetoothDevice device, int state,
            boolean suppressNoisyIntent) {
        final IAudioService service = getService();
        try {
            service.setBluetoothLeAudioOutDeviceConnectionState(device, state, suppressNoisyIntent);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
    * Indicate Le Audio input connection state change.
    * @param device Bluetooth device connected/disconnected
    * @param state new connection state (BluetoothProfile.STATE_xxx)
    * {@hide}
    */
    public void setBluetoothLeAudioInDeviceConnectionState(BluetoothDevice device, int state) {
        final IAudioService service = getService();
        try {
            service.setBluetoothLeAudioInDeviceConnectionState(device, state);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

     /**
     * Indicate A2DP source or sink connection state change and eventually suppress
     * the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent.
     * This operation is asynchronous but its execution will still be sequentially scheduled
     * relative to calls to {@link #setBluetoothHearingAidDeviceConnectionState(BluetoothDevice,
     * int, boolean, int)} and
     * {@link #handleBluetoothA2dpDeviceConfigChange(BluetoothDevice)}.
     * @param device Bluetooth device connected/disconnected
     * @param state  new connection state, {@link BluetoothProfile#STATE_CONNECTED}
     *     or {@link BluetoothProfile#STATE_DISCONNECTED}
     * @param profile profile for the A2DP device
     * @param a2dpVolume New volume for the connecting device. Does nothing if disconnecting.
     * (either {@link android.bluetooth.BluetoothProfile.A2DP} or
     * {@link android.bluetooth.BluetoothProfile.A2DP_SINK})
     * @param suppressNoisyIntent if true the
     * {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be sent.
     * {@hide}
     */
    public void setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
            BluetoothDevice device, int state,
            int profile, boolean suppressNoisyIntent, int a2dpVolume) {
        final IAudioService service = getService();
        try {
            service.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(device,
                state, profile, suppressNoisyIntent, a2dpVolume);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

     /**
     * Indicate A2DP device configuration has changed.
     * This operation is asynchronous but its execution will still be sequentially scheduled
     * relative to calls to
     * {@link #setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(BluetoothDevice, int, int,
     * boolean, int)} and
     * {@link #setBluetoothHearingAidDeviceConnectionState(BluetoothDevice, int, boolean, int)}
     * @param device Bluetooth device whose configuration has changed.
     * Indicate Bluetooth profile connection state change.
     * Configuration changes for A2DP are indicated by having the same <code>newDevice</code> and
     * <code>previousDevice</code>
     * This operation is asynchronous.
     *
     * @param newDevice Bluetooth device connected or null if there is no new devices
     * @param previousDevice Bluetooth device disconnected or null if there is no disconnected
     * devices
     * @param info contain all info related to the device. {@link BtProfileConnectionInfo}
     * {@hide}
     */
    public void handleBluetoothA2dpDeviceConfigChange(BluetoothDevice device) {
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK)
    public void handleBluetoothActiveDeviceChanged(@Nullable BluetoothDevice newDevice,
            @Nullable BluetoothDevice previousDevice, @NonNull BtProfileConnectionInfo info) {
        final IAudioService service = getService();
        try {
            service.handleBluetoothA2dpDeviceConfigChange(device);
            service.handleBluetoothActiveDeviceChanged(newDevice, previousDevice, info);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+20 −0
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 android.media;

parcelable BtProfileConnectionInfo;
+163 −0
Original line number Diff line number Diff line
/*
 * Copyright 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 android.media;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.bluetooth.BluetoothProfile;
import android.os.Parcel;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Contains information about Bluetooth profile connection state changed
 * {@hide}
 */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public final class BtProfileConnectionInfo implements Parcelable {
    /** @hide */
    @IntDef({
            BluetoothProfile.A2DP,
            BluetoothProfile.A2DP_SINK, // Can only be set by BtHelper
            BluetoothProfile.HEADSET, // Can only be set by BtHelper
            BluetoothProfile.HEARING_AID,
            BluetoothProfile.LE_AUDIO,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface BtProfile {}

    private final @BtProfile int mProfile;
    private final boolean mSupprNoisy;
    private final int mVolume;
    private final boolean mIsLeOutput;

    private BtProfileConnectionInfo(@BtProfile int profile, boolean suppressNoisyIntent, int volume,
            boolean isLeOutput) {
        mProfile = profile;
        mSupprNoisy = suppressNoisyIntent;
        mVolume = volume;
        mIsLeOutput = isLeOutput;
    }

    /**
     * Constructor used by BtHelper when a profile is connected
     * {@hide}
     */
    public BtProfileConnectionInfo(@BtProfile int profile) {
        this(profile, false, -1, false);
    }

    public static final @NonNull Parcelable.Creator<BtProfileConnectionInfo> CREATOR =
            new Parcelable.Creator<BtProfileConnectionInfo>() {
                @Override
                public BtProfileConnectionInfo createFromParcel(Parcel source) {
                    return new BtProfileConnectionInfo(source.readInt(), source.readBoolean(),
                            source.readInt(), source.readBoolean());
                }

                @Override
                public BtProfileConnectionInfo[] newArray(int size) {
                    return new BtProfileConnectionInfo[size];
                }
            };

    @Override
    public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
        dest.writeInt(mProfile);
        dest.writeBoolean(mSupprNoisy);
        dest.writeInt(mVolume);
        dest.writeBoolean(mIsLeOutput);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * Constructor for A2dp info
     *
     * @param suppressNoisyIntent if true the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY}
     * intent will not be sent.
     *
     * @param volume of device -1 to ignore value
     */
    public static @NonNull BtProfileConnectionInfo a2dpInfo(boolean suppressNoisyIntent,
            int volume) {
        return new BtProfileConnectionInfo(BluetoothProfile.A2DP, suppressNoisyIntent, volume,
            false);
    }

    /**
     * Constructor for hearing aid info
     *
     * @param suppressNoisyIntent if true the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY}
     * intent will not be sent.
     */
    public static @NonNull BtProfileConnectionInfo hearingAidInfo(boolean suppressNoisyIntent) {
        return new BtProfileConnectionInfo(BluetoothProfile.HEARING_AID, suppressNoisyIntent, -1,
            false);
    }

    /**
     * constructor for le audio info
     *
     * @param suppressNoisyIntent if true the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY}
     * intent will not be sent.
     *
     * @param isLeOutput if true mean the device is an output device, if false it's an input device
     */
    public static @NonNull BtProfileConnectionInfo leAudio(boolean suppressNoisyIntent,
            boolean isLeOutput) {
        return new BtProfileConnectionInfo(BluetoothProfile.LE_AUDIO, suppressNoisyIntent, -1,
            isLeOutput);
    }

    /**
     * @return The profile connection
     */
    public @BtProfile int getProfile() {
        return mProfile;
    }

    /**
     * @return {@code true} if {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be
     * sent
     */
    public boolean getSuppressNoisyIntent() {
        return mSupprNoisy;
    }

    /**
     * Only for {@link BluetoothProfile.A2DP} profile
     * @return the volume of the connection or -1 if the value is ignored
     */
    public int getVolume() {
        return mVolume;
    }

    /**
     * Only for {@link BluetoothProfile.LE_AUDIO} profile
     * @return {@code true} is the LE device is an output device, {@code false} if it's an input
     * device
     */
    public boolean getIsLeOutput() {
        return mIsLeOutput;
    }
}
+3 −12
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.media.AudioFocusInfo;
import android.media.AudioPlaybackConfiguration;
import android.media.AudioRecordingConfiguration;
import android.media.AudioRoutesInfo;
import android.media.BtProfileConnectionInfo;
import android.media.IAudioFocusDispatcher;
import android.media.IAudioModeDispatcher;
import android.media.IAudioRoutesObserver;
@@ -207,8 +208,6 @@ interface IAudioService {
    void setWiredDeviceConnectionState(int type, int state, String address, String name,
            String caller);

    void handleBluetoothA2dpDeviceConfigChange(in BluetoothDevice device);

    @UnsupportedAppUsage
    AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer);

@@ -268,16 +267,8 @@ interface IAudioService {

    oneway void playerHasOpPlayAudio(in int piid, in boolean hasOpPlayAudio);

    void setBluetoothHearingAidDeviceConnectionState(in BluetoothDevice device,
            int state, boolean suppressNoisyIntent, int musicDevice);

    void setBluetoothLeAudioOutDeviceConnectionState(in BluetoothDevice device, int state,
            boolean suppressNoisyIntent);

    void setBluetoothLeAudioInDeviceConnectionState(in BluetoothDevice device, int state);

    void setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(in BluetoothDevice device,
            int state, int profile, boolean suppressNoisyIntent, int a2dpVolume);
    void handleBluetoothActiveDeviceChanged(in BluetoothDevice newDevice,
            in BluetoothDevice previousDevice, in BtProfileConnectionInfo info);

    oneway void setFocusRequestResultFromExtPolicy(in AudioFocusInfo afi, int requestResult,
            in IAudioPolicyCallback pcb);
Loading