[Audiosharing] Add toggle to improve sharing compatibility.
Test: manual
Bug: 305620450
Bug: 292538935
Change-Id: I8df92323c606cc3375a0f985d46c11caa12c6cfe
diff --git a/res/xml/bluetooth_audio_sharing.xml b/res/xml/bluetooth_audio_sharing.xml
index dc577f6..d3aad22 100644
--- a/res/xml/bluetooth_audio_sharing.xml
+++ b/res/xml/bluetooth_audio_sharing.xml
@@ -48,6 +48,10 @@
android:summary="********"
android:title="Stream name"
settings:controller="com.android.settings.connecteddevice.audiosharing.AudioSharingNamePreferenceController" />
+ <SwitchPreferenceCompat
+ android:key="audio_sharing_stream_compatibility"
+ android:title="Improve compatibility"
+ settings:controller="com.android.settings.connecteddevice.audiosharing.AudioSharingCompatibilityPreferenceController" />
</PreferenceCategory>
<PreferenceCategory
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCompatibilityPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCompatibilityPreferenceController.java
new file mode 100644
index 0000000..9dda0a1
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCompatibilityPreferenceController.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2024 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.settings.connecteddevice.audiosharing;
+
+import android.bluetooth.BluetoothLeBroadcast;
+import android.bluetooth.BluetoothLeBroadcastMetadata;
+import android.content.Context;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.TwoStatePreference;
+
+import com.android.settings.bluetooth.Utils;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+public class AudioSharingCompatibilityPreferenceController extends TogglePreferenceController
+ implements DefaultLifecycleObserver {
+
+ private static final String TAG = "AudioSharingCompatibilityPrefController";
+
+ private static final String PREF_KEY = "audio_sharing_stream_compatibility";
+ private static final String SHARING_OFF_SUMMARY =
+ "Helps some devices like hearing aids connect by reducing audio quality";
+ private static final String SHARING_ON_SUMMARY =
+ "Turns off the audio sharing to config the compatibility";
+
+ private final LocalBluetoothManager mBtManager;
+ private final Executor mExecutor;
+ private final LocalBluetoothLeBroadcast mBroadcast;
+ @Nullable private TwoStatePreference mPreference;
+
+ private final BluetoothLeBroadcast.Callback mBroadcastCallback =
+ new BluetoothLeBroadcast.Callback() {
+ @Override
+ public void onBroadcastStarted(int reason, int broadcastId) {
+ Log.d(
+ TAG,
+ "onBroadcastStarted(), reason = "
+ + reason
+ + ", broadcastId = "
+ + broadcastId);
+ updateEnabled();
+ }
+
+ @Override
+ public void onBroadcastStartFailed(int reason) {}
+
+ @Override
+ public void onBroadcastMetadataChanged(
+ int broadcastId, @NonNull BluetoothLeBroadcastMetadata metadata) {}
+
+ @Override
+ public void onBroadcastStopped(int reason, int broadcastId) {
+ Log.d(
+ TAG,
+ "onBroadcastStopped(), reason = "
+ + reason
+ + ", broadcastId = "
+ + broadcastId);
+ updateEnabled();
+ }
+
+ @Override
+ public void onBroadcastStopFailed(int reason) {}
+
+ @Override
+ public void onBroadcastUpdated(int reason, int broadcastId) {}
+
+ @Override
+ public void onBroadcastUpdateFailed(int reason, int broadcastId) {}
+
+ @Override
+ public void onPlaybackStarted(int reason, int broadcastId) {}
+
+ @Override
+ public void onPlaybackStopped(int reason, int broadcastId) {}
+ };
+
+ public AudioSharingCompatibilityPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ mBtManager = Utils.getLocalBtManager(context);
+ mBroadcast = mBtManager.getProfileManager().getLeAudioBroadcastProfile();
+ mExecutor = Executors.newSingleThreadExecutor();
+ }
+
+ @Override
+ public void onStart(@NonNull LifecycleOwner owner) {
+ if (mBroadcast != null) {
+ mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback);
+ }
+ }
+
+ @Override
+ public void onStop(@NonNull LifecycleOwner owner) {
+ if (mBroadcast != null) {
+ mBroadcast.unregisterServiceCallBack(mBroadcastCallback);
+ }
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(getPreferenceKey());
+ updateEnabled();
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return PREF_KEY;
+ }
+
+ @Override
+ public boolean isChecked() {
+ // TODO: return real compatibility config.
+ return false;
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ if (mBroadcast == null) {
+ return false;
+ }
+ // TODO: set real compatibility config.
+ return true;
+ }
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return 0;
+ }
+
+ private void updateEnabled() {
+ mContext.getMainExecutor()
+ .execute(
+ () -> {
+ if (mPreference != null) {
+ boolean isBroadcasting =
+ AudioSharingUtils.isBroadcasting(mBtManager);
+ mPreference.setEnabled(!isBroadcasting);
+ mPreference.setSummary(
+ isBroadcasting ? SHARING_ON_SUMMARY : SHARING_OFF_SUMMARY);
+ }
+ });
+ }
+}