Loading src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java +26 −26 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading @@ -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 Loading @@ -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; } } Loading @@ -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; } Loading @@ -130,7 +130,7 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater Log.d( TAG, "isFilterMatched() device : " + cachedDevice.getName() + deviceName + ", isFilterMatched : " + isFilterMatched); } Loading src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java +40 −36 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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, Loading @@ -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; Loading src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java +63 −29 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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(); Loading Loading @@ -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(); } Loading @@ -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(); } Loading Loading @@ -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(); Loading Loading @@ -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 Loading @@ -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) Loading @@ -356,7 +391,6 @@ public class AvailableMediaDeviceGroupController extends BasePreferenceControlle mPreferenceGroup.setTitle(titleResId); } }); }); } private void registerAudioSharingCallbacks() { Loading src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java +49 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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"; Loading Loading @@ -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(); Loading Loading @@ -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, Loading Loading @@ -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; } Loading tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java +41 −32 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java +26 −26 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading @@ -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 Loading @@ -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; } } Loading @@ -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; } Loading @@ -130,7 +130,7 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater Log.d( TAG, "isFilterMatched() device : " + cachedDevice.getName() + deviceName + ", isFilterMatched : " + isFilterMatched); } Loading
src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java +40 −36 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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, Loading @@ -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; Loading
src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java +63 −29 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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(); Loading Loading @@ -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(); } Loading @@ -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(); } Loading Loading @@ -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(); Loading Loading @@ -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 Loading @@ -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) Loading @@ -356,7 +391,6 @@ public class AvailableMediaDeviceGroupController extends BasePreferenceControlle mPreferenceGroup.setTitle(titleResId); } }); }); } private void registerAudioSharingCallbacks() { Loading
src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java +49 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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"; Loading Loading @@ -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(); Loading Loading @@ -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, Loading Loading @@ -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; } Loading
tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java +41 −32 File changed.Preview size limit exceeded, changes collapsed. Show changes