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

Commit addf3059 authored by chelseahao's avatar chelseahao
Browse files

Move audio stream entry point to connection preference page.

Test: atest
Bug: 405280569
Flag: com.android.settingslib.flags.enable_le_audio_sharing
Change-Id: I6aaaa8f658262ec5aae9f049ce62c75f17a4a93f
parent b96eb497
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -14267,6 +14267,10 @@ Data usage charges may apply.</string>
    <string name="audio_streams_qr_code_page_password">Password: <xliff:g example="123" id="password">%1$s</xliff:g></string>
    <!-- Le audio streams qr code page description [CHAR LIMIT=NONE] -->
    <string name="audio_streams_qr_code_page_description">To listen to <xliff:g example="Local Music" id="stream_name">%1$s</xliff:g>, other people can connect compatible headphones to their Android device. They can then scan this QR code.</string>
    <!-- Le audio streams preference subtitle [CHAR LIMIT=NONE] -->
    <string name="audio_streams_preference_subtitle">Listen to Auracast broadcast</string>
    <!-- Le audio streams preference subtitle when audio sharing is on[CHAR LIMIT=NONE] -->
    <string name="audio_streams_preference_subtitle_audio_sharing_on">Turn off audio sharing to find audio streams</string>
    <!-- Le audio streams main page title [CHAR LIMIT=NONE] -->
    <string name="audio_streams_main_page_title">Find an audio stream</string>
    <!-- Le audio streams main page subtitle [CHAR LIMIT=NONE] -->
+0 −13
Original line number Diff line number Diff line
@@ -65,17 +65,4 @@
            android:title="@string/audio_sharing_stream_compatibility_title"
            settings:controller="com.android.settings.connecteddevice.audiosharing.AudioSharingCompatibilityPreferenceController" />
    </PreferenceCategory>

    <PreferenceCategory
        android:key="audio_streams_settings_category"
        android:title="@string/audio_sharing_nearby_audio_title"
        settings:controller="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsCategoryController">

        <Preference
            android:fragment="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsDashboardFragment"
            android:icon="@drawable/ic_chevron_right_24dp"
            android:key="audio_streams_settings"
            android:title="@string/audio_streams_main_page_title" />

    </PreferenceCategory>
</PreferenceScreen>
 No newline at end of file
+11 −2
Original line number Diff line number Diff line
@@ -23,18 +23,27 @@
        android:fragment="com.android.settings.connecteddevice.BluetoothDashboardFragment"
        android:icon="@*android:drawable/ic_settings_bluetooth"
        android:key="bluetooth_switchbar_screen"
        android:order="-10"
        android:order="-11"
        android:title="@string/bluetooth_settings_title" />

    <Preference
        android:fragment="com.android.settings.connecteddevice.audiosharing.AudioSharingDashboardFragment"
        android:icon="@drawable/ic_bt_le_audio_sharing"
        android:key="audio_sharing_settings"
        android:order="-9"
        android:order="-10"
        android:title="@string/audio_sharing_title"
        settings:controller="com.android.settings.connecteddevice.audiosharing.AudioSharingPreferenceController"
        settings:searchable="true" />

    <Preference
        android:fragment="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsDashboardFragment"
        android:icon="@drawable/ic_bt_le_audio_sharing"
        android:key="audio_streams_settings"
        android:order="-9"
        android:title="@string/audio_streams_pref_title"
        settings:controller="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsCategoryController"
        settings:searchable="true" />

    <com.android.settingslib.RestrictedPreference
        android:fragment="com.android.settings.connecteddevice.NfcAndPaymentFragment"
        android:icon="@drawable/ic_nfc"
+0 −6
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import androidx.annotation.VisibleForTesting;

import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsCategoryController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.widget.SettingsMainSwitchBar;
import com.android.settingslib.bluetooth.BluetoothUtils;
@@ -55,7 +54,6 @@ public class AudioSharingDashboardFragment extends DashboardFragment
    private AudioSharingDeviceVolumeGroupController mAudioSharingDeviceVolumeGroupController;
    private AudioSharingCallAudioPreferenceController mAudioSharingCallAudioPreferenceController;
    private AudioSharingPlaySoundPreferenceController mAudioSharingPlaySoundPreferenceController;
    private AudioStreamsCategoryController mAudioStreamsCategoryController;
    private AudioSharingSwitchBarController mAudioSharingSwitchBarController;

    public AudioSharingDashboardFragment() {
@@ -94,7 +92,6 @@ public class AudioSharingDashboardFragment extends DashboardFragment
        mAudioSharingCallAudioPreferenceController.init(this);
        mAudioSharingPlaySoundPreferenceController =
                use(AudioSharingPlaySoundPreferenceController.class);
        mAudioStreamsCategoryController = use(AudioStreamsCategoryController.class);
    }

    @Override
@@ -184,12 +181,10 @@ public class AudioSharingDashboardFragment extends DashboardFragment
            AudioSharingDeviceVolumeGroupController volumeGroupController,
            AudioSharingCallAudioPreferenceController callAudioController,
            AudioSharingPlaySoundPreferenceController playSoundController,
            AudioStreamsCategoryController streamsCategoryController,
            AudioSharingSwitchBarController switchBarController) {
        mAudioSharingDeviceVolumeGroupController = volumeGroupController;
        mAudioSharingCallAudioPreferenceController = callAudioController;
        mAudioSharingPlaySoundPreferenceController = playSoundController;
        mAudioStreamsCategoryController = streamsCategoryController;
        mAudioSharingSwitchBarController = switchBarController;
    }

@@ -197,7 +192,6 @@ public class AudioSharingDashboardFragment extends DashboardFragment
        mAudioSharingDeviceVolumeGroupController.updateVisibility();
        mAudioSharingCallAudioPreferenceController.updateVisibility();
        mAudioSharingPlaySoundPreferenceController.updateVisibility();
        mAudioStreamsCategoryController.updateVisibility();
    }

    private void onProfilesConnectedForAttachedPreferences() {
+109 −77
Original line number Diff line number Diff line
@@ -16,117 +16,149 @@

package com.android.settings.connecteddevice.audiosharing.audiostreams;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothProfile;
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.annotation.VisibleForTesting;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
import com.android.settings.connecteddevice.audiosharing.AudioSharingBasePreferenceController;
import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;

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

public class AudioStreamsCategoryController extends AudioSharingBasePreferenceController {
public class AudioStreamsCategoryController extends BasePreferenceController
        implements DefaultLifecycleObserver {
    private static final String TAG = "AudioStreamsCategoryController";
    private static final boolean DEBUG = BluetoothUtils.D;
    private final LocalBluetoothManager mLocalBtManager;

    @Nullable
    private final LocalBluetoothManager mBtManager;
    @Nullable
    private final LocalBluetoothLeBroadcast mBroadcast;
    @Nullable
    private Preference mPreference;
    private final Executor mExecutor;
    private final BluetoothCallback mBluetoothCallback =
            new BluetoothCallback() {

    @VisibleForTesting
    final BluetoothLeBroadcast.Callback mBroadcastCallback =
            new BluetoothLeBroadcast.Callback() {
                @Override
                public void onBroadcastStarted(int reason, int broadcastId) {
                    if (mPreference != null) {
                        updateState(mPreference);
                    }
                }

                @Override
                public void onProfileConnectionStateChanged(
                        @NonNull CachedBluetoothDevice cachedDevice,
                        @ConnectionState int state,
                        int bluetoothProfile) {
                    if (bluetoothProfile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT
                            && (state == BluetoothAdapter.STATE_CONNECTED
                                    || state == BluetoothAdapter.STATE_DISCONNECTED)) {
                        updateVisibility();
                public void onBroadcastStartFailed(int reason) {
                }

                @Override
                public void onBroadcastMetadataChanged(
                        int broadcastId, @NonNull BluetoothLeBroadcastMetadata metadata) {
                }

                @Override
                public void onBroadcastStopped(int reason, int broadcastId) {
                    if (mPreference != null) {
                        updateState(mPreference);
                    }
                }

                @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 AudioStreamsCategoryController(Context context, String key) {
        super(context, key);
        mLocalBtManager = Utils.getLocalBtManager(mContext);
    public AudioStreamsCategoryController(Context context, String preferenceKey) {
        super(context, preferenceKey);
        mBtManager = Utils.getLocalBtManager(context);
        mBroadcast =
                mBtManager == null
                        ? null
                        : mBtManager.getProfileManager().getLeAudioBroadcastProfile();
        mExecutor = Executors.newSingleThreadExecutor();
    }

    @Override
    public void onStart(@NonNull LifecycleOwner owner) {
        if (!isAvailable()) return;
        super.onStart(owner);
        if (mLocalBtManager != null) {
            mLocalBtManager.getEventManager().registerCallback(mBluetoothCallback);
        if (!isAvailable()) {
            Log.d(TAG, "Skip register callbacks, feature not support");
            return;
        }
        if (mBroadcast == null) {
            Log.d(TAG, "Skip register callbacks, profile not ready");
            return;
        }
        mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback);
    }

    @Override
    public void onStop(@NonNull LifecycleOwner owner) {
        if (!isAvailable()) return;
        super.onStop(owner);
        if (mLocalBtManager != null) {
            mLocalBtManager.getEventManager().unregisterCallback(mBluetoothCallback);
        if (!isAvailable()) {
            Log.d(TAG, "Skip unregister callbacks, feature not support");
            return;
        }
        if (mBroadcast == null) {
            Log.d(TAG, "Skip register callbacks, profile not ready");
            return;
        }
        mBroadcast.unregisterServiceCallBack(mBroadcastCallback);
    }

    @Override
    public void updateVisibility() {
        if (mPreference == null) return;
        mExecutor.execute(
                () -> {
                    if (!isAvailable()) {
                        Log.d(TAG, "skip updateVisibility, unavailable preference");
                        AudioSharingUtils.postOnMainThread(
                                mContext,
                                () -> { // Check nullability to pass NullAway check
                                    if (mPreference != null) {
                                        mPreference.setVisible(false);
    public void displayPreference(@NonNull PreferenceScreen screen) {
        super.displayPreference(screen);
        mPreference = screen.findPreference(getPreferenceKey());
    }

    @Override
    public void updateState(Preference preference) {
        AudioSharingUtils.postOnMainThread(mContext, () -> {
            refreshSummary(preference);
            preference.setEnabled(!BluetoothUtils.isBroadcasting(mBtManager));
        });
                        return;
    }
                    boolean hasConnectedLe =
                            AudioStreamsHelper.getCachedBluetoothDeviceInSharingOrLeConnected(
                                            mLocalBtManager)
                                    .isPresent();
                    boolean isProfileReady =
                            AudioSharingUtils.isAudioSharingProfileReady(
                                    mLocalBtManager.getProfileManager());
                    boolean isBroadcasting = isBroadcasting();
                    boolean isBluetoothOn = isBluetoothStateOn();
                    if (DEBUG) {
                        Log.d(
                                TAG,
                                "updateVisibility() isBroadcasting : "
                                        + isBroadcasting
                                        + " hasConnectedLe : "
                                        + hasConnectedLe
                                        + " is BT on : "
                                        + isBluetoothOn
                                        + " is profile ready : "
                                        + isProfileReady);
                    }
                    AudioSharingUtils.postOnMainThread(
                            mContext,
                            () -> { // Check nullability to pass NullAway check
                                if (mPreference != null) {
                                    mPreference.setVisible(
                                            isProfileReady
                                                    && isBluetoothOn
                                                    && hasConnectedLe
                                                    && !isBroadcasting);

    @Override
    public int getAvailabilityStatus() {
        return BluetoothUtils.isAudioSharingUIAvailable(mContext) ? AVAILABLE
                : UNSUPPORTED_ON_DEVICE;
    }
                            });
                });

    @Override
    public CharSequence getSummary() {
        return BluetoothUtils.isBroadcasting(mBtManager)
                ? mContext.getString(R.string.audio_streams_preference_subtitle_audio_sharing_on)
                : mContext.getString(R.string.audio_streams_preference_subtitle);
    }
}
Loading