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

Commit 6d814e16 authored by Chelsea Hao's avatar Chelsea Hao Committed by Android (Google) Code Review
Browse files

Merge "Move audio stream entry point to connection preference page." into main

parents 58c9eac6 addf3059
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -14297,6 +14297,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