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

Commit 76887f21 authored by Yiyi Shen's avatar Yiyi Shen Committed by Android (Google) Code Review
Browse files

Merge "Fix the audio mode status when missing onAudioModeChanged" into main

parents 1cc0d5f8 d53731b5
Loading
Loading
Loading
Loading
+26 −26
Original line number Diff line number Diff line
@@ -15,9 +15,10 @@
 */
package com.android.settings.bluetooth;

import static com.android.settingslib.Utils.isAudioModeOngoingCall;

import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.media.AudioManager;
import android.util.Log;

import androidx.preference.Preference;
@@ -28,43 +29,43 @@ import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.utils.ThreadUtils;

import java.util.concurrent.atomic.AtomicBoolean;

/** Controller to maintain available media Bluetooth devices */
public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater
        implements Preference.OnPreferenceClickListener {

    private static final String TAG = "AvailableMediaBluetoothDeviceUpdater";
    private static final boolean DBG = Log.isLoggable(BluetoothDeviceUpdater.TAG, Log.DEBUG);

    private static final String PREF_KEY_PREFIX = "available_media_bt_";

    private final AudioManager mAudioManager;
    private final LocalBluetoothManager mLocalBtManager;
    private int mAudioMode;
    private AtomicBoolean mIsOngoingCall = new AtomicBoolean(false);

    public AvailableMediaBluetoothDeviceUpdater(
            Context context,
            DevicePreferenceCallback devicePreferenceCallback,
            int metricsCategory) {
        super(context, devicePreferenceCallback, metricsCategory);
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        mLocalBtManager = Utils.getLocalBtManager(context);
        mAudioMode = mAudioManager.getMode();
        var unused =
                ThreadUtils.postOnBackgroundThread(
                        () -> mIsOngoingCall.set(isAudioModeOngoingCall(mContext)));
    }

    @Override
    public void onAudioModeChanged() {
        // TODO: move to background thread
        mAudioMode = mAudioManager.getMode();
        forceUpdate();
    /**
     * Set if the device is in ongoing call mode.
     *
     * <p>This should be set whe the activity is onStart and when audio mode is changed.
     */
    public void setIsOngoingCall(boolean isOngoingCall) {
        mIsOngoingCall.set(isOngoingCall);
    }

    @Override
    public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
        final int currentAudioProfile;

        if (mAudioMode == AudioManager.MODE_RINGTONE
                || mAudioMode == AudioManager.MODE_IN_CALL
                || mAudioMode == AudioManager.MODE_IN_COMMUNICATION) {
        if (mIsOngoingCall.get()) {
            // in phone call
            currentAudioProfile = BluetoothProfile.HEADSET;
        } else {
@@ -75,6 +76,7 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater
        boolean isFilterMatched = false;
        if (isDeviceConnected(cachedDevice) && isDeviceInCachedDevicesList(cachedDevice)) {
            Log.d(TAG, "isFilterMatched() current audio profile : " + currentAudioProfile);
            String deviceName = cachedDevice.getName();

            // If device is LE Audio, it is compatible with HFP and A2DP.
            // It would show in Available Devices group if the audio sharing flag is disabled or
@@ -86,18 +88,16 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater
                                cachedDevice, mLocalBtManager)) {
                    Log.d(
                            TAG,
                            "Filter out device : "
                                    + cachedDevice.getName()
                                    + ", it is in audio sharing.");
                            "isFilterMatched() device : "
                                    + deviceName
                                    + ", isFilterMatched : false, in audio sharing.");
                    return false;

                } else {
                    Log.d(
                            TAG,
                            "isFilterMatched() device : "
                                    + cachedDevice.getName()
                                    + ", the LE Audio profile is connected and not in sharing "
                                    + "if broadcast enabled.");
                                    + deviceName
                                    + ", isFilterMatched : true, the LEA profile is connected.");
                    return true;
                }
            }
@@ -108,8 +108,8 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater
                Log.d(
                        TAG,
                        "isFilterMatched() device : "
                                + cachedDevice.getName()
                                + ", the Hearing Aid profile is connected.");
                                + deviceName
                                + ", isFilterMatched : true, the HA profile is connected.");
                return true;
            }

@@ -130,7 +130,7 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater
            Log.d(
                    TAG,
                    "isFilterMatched() device : "
                            + cachedDevice.getName()
                            + deviceName
                            + ", isFilterMatched : "
                            + isFilterMatched);
        }
+40 −36
Original line number Diff line number Diff line
@@ -15,52 +15,55 @@
 */
package com.android.settings.bluetooth;

import static com.android.settingslib.Utils.isAudioModeOngoingCall;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.media.AudioManager;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.preference.Preference;

import com.android.settings.connecteddevice.DevicePreferenceCallback;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.utils.ThreadUtils;

/**
 * Controller to maintain connected bluetooth devices
 */
import java.util.concurrent.atomic.AtomicBoolean;

/** Controller to maintain connected bluetooth devices */
public class ConnectedBluetoothDeviceUpdater extends BluetoothDeviceUpdater {

    private static final String TAG = "ConnBluetoothDeviceUpdater";
    private static final boolean DBG = Log.isLoggable(BluetoothDeviceUpdater.TAG, Log.DEBUG);

    private static final String PREF_KEY_PREFIX = "connected_bt_";
    private AtomicBoolean mIsOngoingCall = new AtomicBoolean(false);

    private final AudioManager mAudioManager;
    private int mAudioMode;

    public ConnectedBluetoothDeviceUpdater(Context context,
            DevicePreferenceCallback devicePreferenceCallback, int metricsCategory) {
    public ConnectedBluetoothDeviceUpdater(
            @NonNull Context context,
            @NonNull DevicePreferenceCallback devicePreferenceCallback,
            int metricsCategory) {
        super(context, devicePreferenceCallback, metricsCategory);
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        mAudioMode = mAudioManager.getMode();
        var unused =
                ThreadUtils.postOnBackgroundThread(
                        () -> mIsOngoingCall.set(isAudioModeOngoingCall(mContext)));
    }

    @Override
    public void onAudioModeChanged() {
        // TODO: move to background thread
        mAudioMode = mAudioManager.getMode();
        forceUpdate();
    /**
     * Set if the device is in ongoing call mode.
     *
     * <p>This should be set whe the activity is onStart and when audio mode is changed.
     */
    public void setIsOngoingCall(boolean isOngoingCall) {
        mIsOngoingCall.set(isOngoingCall);
    }

    @Override
    public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
        final int currentAudioProfile;

        if (mAudioMode == AudioManager.MODE_RINGTONE
                || mAudioMode == AudioManager.MODE_IN_CALL
                || mAudioMode == AudioManager.MODE_IN_COMMUNICATION) {
        if (mIsOngoingCall.get()) {
            // in phone call
            currentAudioProfile = BluetoothProfile.HEADSET;
        } else {
@@ -70,18 +73,19 @@ public class ConnectedBluetoothDeviceUpdater extends BluetoothDeviceUpdater {

        boolean isFilterMatched = false;
        if (isDeviceConnected(cachedDevice) && isDeviceInCachedDevicesList(cachedDevice)) {
            if (DBG) {
            Log.d(TAG, "isFilterMatched() current audio profile : " + currentAudioProfile);
            }
            String deviceName = cachedDevice.getName();

            // If device is Hearing Aid or LE Audio, it is compatible with HFP and A2DP.
            // It would not show in Connected Devices group.
            if (cachedDevice.isConnectedAshaHearingAidDevice()
                    || cachedDevice.isConnectedLeAudioDevice()
                    || cachedDevice.hasConnectedLeAudioMemberDevice()) {
                if (DBG) {
                    Log.d(TAG, "isFilterMatched() device : " + cachedDevice.getName()
                            + ", isFilterMatched : false, ha or lea device");
                }
                Log.d(
                        TAG,
                        "isFilterMatched() device : "
                                + deviceName
                                + ", isFilterMatched : false, HA or LEA profile connected");
                return false;
            }
            // According to the current audio profile type,
@@ -99,16 +103,16 @@ public class ConnectedBluetoothDeviceUpdater extends BluetoothDeviceUpdater {
                    isFilterMatched = !cachedDevice.isConnectedHfpDevice();
                    break;
            }
            if (DBG) {
                Log.d(TAG, "isFilterMatched() device : " +
                        cachedDevice.getName() + ", isFilterMatched : " + isFilterMatched);
            }
            Log.d(
                    TAG,
                    "isFilterMatched() device : "
                            + deviceName
                            + ", isFilterMatched : "
                            + isFilterMatched);
        }
        if (BluetoothUtils.isExclusivelyManagedBluetoothDevice(mContext,
                cachedDevice.getDevice())) {
            if (DBG) {
        if (BluetoothUtils.isExclusivelyManagedBluetoothDevice(
                mContext, cachedDevice.getDevice())) {
            Log.d(TAG, "isFilterMatched() hide BluetoothDevice with exclusive manager");
            }
            return false;
        }
        return isFilterMatched;
+63 −29
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
@@ -58,6 +59,7 @@ import com.android.settingslib.utils.ThreadUtils;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Controller to maintain the {@link androidx.preference.PreferenceGroup} for all available media
@@ -76,6 +78,7 @@ public class AvailableMediaDeviceGroupController extends BasePreferenceControlle
    @Nullable private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
    @Nullable private FragmentManager mFragmentManager;
    @Nullable private AudioSharingDialogHandler mDialogHandler;
    private AtomicBoolean mIsOngoingCall = new AtomicBoolean(false);
    private BluetoothLeBroadcast.Callback mBroadcastCallback =
            new BluetoothLeBroadcast.Callback() {
                @Override
@@ -131,8 +134,7 @@ public class AvailableMediaDeviceGroupController extends BasePreferenceControlle
                public void onSourceFound(@NonNull BluetoothLeBroadcastMetadata source) {}

                @Override
                public void onSourceAdded(
                        @NonNull BluetoothDevice sink, int sourceId, int reason) {
                public void onSourceAdded(@NonNull BluetoothDevice sink, int sourceId, int reason) {
                    Log.d(TAG, "onSourceAdded: update media device list.");
                    if (mBluetoothDeviceUpdater != null) {
                        mBluetoothDeviceUpdater.forceUpdate();
@@ -191,13 +193,25 @@ public class AvailableMediaDeviceGroupController extends BasePreferenceControlle

    @Override
    public void onStart(@NonNull LifecycleOwner owner) {
        if (isAvailable()) {
            updateTitle();
        }
        if (mBtManager == null) {
            Log.d(TAG, "onStart() Bluetooth is not supported on this device");
            return;
        }
        if (!isAvailable()) {
            Log.d(TAG, "onStart() Bluetooth feature is not available on this device");
            return;
        }
        var unused =
                ThreadUtils.postOnBackgroundThread(
                        () -> {
                            boolean isOngoingCall = isAudioModeOngoingCall(mContext);
                            mIsOngoingCall.set(isOngoingCall);
                            if (mBluetoothDeviceUpdater
                                    instanceof AvailableMediaBluetoothDeviceUpdater updater) {
                                updater.setIsOngoingCall(isOngoingCall);
                            }
                            updateTitle();
                        });
        if (BluetoothUtils.isAudioSharingUIAvailable(mContext)) {
            registerAudioSharingCallbacks();
        }
@@ -214,6 +228,10 @@ public class AvailableMediaDeviceGroupController extends BasePreferenceControlle
            Log.d(TAG, "onStop() Bluetooth is not supported on this device");
            return;
        }
        if (!isAvailable()) {
            Log.d(TAG, "onStop() Bluetooth feature is not available on this device");
            return;
        }
        if (BluetoothUtils.isAudioSharingUIAvailable(mContext)) {
            unregisterAudioSharingCallbacks();
        }
@@ -278,7 +296,8 @@ public class AvailableMediaDeviceGroupController extends BasePreferenceControlle
                ((BluetoothDevicePreference) preference).getBluetoothDevice();
        if (BluetoothUtils.isAudioSharingUIAvailable(mContext) && mDialogHandler != null) {
            mDialogHandler.handleDeviceConnected(cachedDevice, /* userTriggered= */ true);
            FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
            FeatureFactory.getFeatureFactory()
                    .getMetricsFeatureProvider()
                    .action(mContext, SettingsEnums.ACTION_MEDIA_DEVICE_CLICK);
        } else {
            cachedDevice.setActive();
@@ -314,7 +333,25 @@ public class AvailableMediaDeviceGroupController extends BasePreferenceControlle

    @Override
    public void onAudioModeChanged() {
        var unused =
                ThreadUtils.postOnBackgroundThread(
                        () -> {
                            boolean isOngoingCall = isAudioModeOngoingCall(mContext);
                            mIsOngoingCall.set(isOngoingCall);
                            Log.d(TAG, "onAudioModeChanged, in call mode = " + isOngoingCall);
                            if (mBluetoothDeviceUpdater
                                    instanceof AvailableMediaBluetoothDeviceUpdater updater) {
                                updater.setIsOngoingCall(isOngoingCall);
                            }
                            updateTitle();
                            mContext.getMainExecutor()
                                    .execute(
                                            () -> {
                                                if (mBluetoothDeviceUpdater != null) {
                                                    mBluetoothDeviceUpdater.forceUpdate();
                                                }
                                            });
                        });
    }

    @Override
@@ -330,14 +367,12 @@ public class AvailableMediaDeviceGroupController extends BasePreferenceControlle
        }
    }

    @WorkerThread
    private void updateTitle() {
        if (mPreferenceGroup == null) return;
        var unused =
                ThreadUtils.postOnBackgroundThread(
                        () -> {
        Log.d(TAG, "updateTitle, check current status");
        int titleResId;
                            if (isAudioModeOngoingCall(mContext)) {
        if (mIsOngoingCall.get()) {
            // in phone call
            titleResId = R.string.connected_device_call_device_title;
        } else if (BluetoothUtils.isAudioSharingUIAvailable(mContext)
@@ -356,7 +391,6 @@ public class AvailableMediaDeviceGroupController extends BasePreferenceControlle
                                mPreferenceGroup.setTitle(titleResId);
                            }
                        });
                        });
    }

    private void registerAudioSharingCallbacks() {
+49 −6
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.settings.connecteddevice;

import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.isExternalDisplaySettingsPageEnabled;
import static com.android.settingslib.Utils.isAudioModeOngoingCall;

import android.content.Context;
import android.content.pm.PackageManager;
@@ -46,6 +47,7 @@ import com.android.settings.flags.FeatureFlags;
import com.android.settings.flags.FeatureFlagsImpl;
import com.android.settings.overlay.DockUpdaterFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -54,6 +56,7 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import com.android.settingslib.search.SearchIndexableRaw;
import com.android.settingslib.utils.ThreadUtils;

import java.util.List;

@@ -62,8 +65,12 @@ import java.util.List;
 * connected devices. It uses {@link DevicePreferenceCallback} to add/remove {@link Preference}
 */
public class ConnectedDeviceGroupController extends BasePreferenceController
        implements PreferenceControllerMixin, LifecycleObserver, OnStart, OnStop,
        DevicePreferenceCallback {
        implements PreferenceControllerMixin,
                LifecycleObserver,
                OnStart,
                OnStop,
                DevicePreferenceCallback,
                BluetoothCallback {

    private static final String KEY = "connected_device_list";
    private static final String TAG = "ConnectedDeviceGroupController";
@@ -96,10 +103,25 @@ public class ConnectedDeviceGroupController extends BasePreferenceController
            mExternalDisplayUpdater.refreshPreference();
        }

        if (mBluetoothDeviceUpdater != null) {
            var unused =
                    ThreadUtils.postOnBackgroundThread(
                            () -> {
                                boolean isOngoingCall = isAudioModeOngoingCall(mContext);
                                if (mBluetoothDeviceUpdater
                                        instanceof ConnectedBluetoothDeviceUpdater updater) {
                                    updater.setIsOngoingCall(isOngoingCall);
                                }
                                mContext.getMainExecutor()
                                        .execute(
                                                () -> {
                                                    if (mBluetoothDeviceUpdater != null) {
                                                        mBluetoothDeviceUpdater.registerCallback();
                                                        mBluetoothDeviceUpdater.refreshPreference();
                                                    }
                                                });
                            });
        }

        if (mConnectedUsbDeviceUpdater != null) {
            mConnectedUsbDeviceUpdater.registerCallback();
@@ -203,6 +225,27 @@ public class ConnectedDeviceGroupController extends BasePreferenceController
        }
    }

    @Override
    public void onAudioModeChanged() {
        var unused =
                ThreadUtils.postOnBackgroundThread(
                        () -> {
                            boolean isOngoingCall = isAudioModeOngoingCall(mContext);
                            Log.d(TAG, "onAudioModeChanged, in call mode = " + isOngoingCall);
                            if (mBluetoothDeviceUpdater
                                    instanceof ConnectedBluetoothDeviceUpdater updater) {
                                updater.setIsOngoingCall(isOngoingCall);
                            }
                            mContext.getMainExecutor()
                                    .execute(
                                            () -> {
                                                if (mBluetoothDeviceUpdater != null) {
                                                    mBluetoothDeviceUpdater.forceUpdate();
                                                }
                                            });
                        });
    }

    @VisibleForTesting
    void init(@Nullable ExternalDisplayUpdater externalDisplayUpdater,
            BluetoothDeviceUpdater bluetoothDeviceUpdater,
@@ -262,8 +305,8 @@ public class ConnectedDeviceGroupController extends BasePreferenceController
    }

    private boolean hasUsiStylusFeature() {
        if (!FeatureFlagUtils.isEnabled(mContext,
                FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES)) {
        if (!FeatureFlagUtils.isEnabled(
                mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES)) {
            return false;
        }

+41 −32

File changed.

Preview size limit exceeded, changes collapsed.

Loading