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

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

Merge changes I885485a5,I4f8e19f5,I3449499a,I08a2b1aa into main

* changes:
  Move `BluetoothUtils.isAudioSharingEnabled` away from `AudioSharingModule` as it contains binder call.
  Listen to audio sharing state change and add the audio sharing source to device if ready.
  Implement onclick behavior for audio sharing dialog buttons.
  Audio sharing dialog on top of bt qs tile dialog.
parents acdf0735 c8821821
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -68,3 +68,44 @@ val LocalBluetoothLeBroadcast.onBroadcastStartedOrStopped: Flow<Unit>
                awaitClose { unregisterServiceCallBack(listener) }
            }
            .buffer(capacity = Channel.CONFLATED)

/** [Flow] for [BluetoothLeBroadcast.Callback] onPlaybackStarted event */
val LocalBluetoothLeBroadcast.onPlaybackStarted: Flow<Unit>
    get() =
        callbackFlow {
            val listener =
                object : BluetoothLeBroadcast.Callback {
                    override fun onBroadcastStarted(reason: Int, broadcastId: Int) {}

                    override fun onBroadcastStartFailed(reason: Int) {
                    }

                    override fun onBroadcastStopped(reason: Int, broadcastId: Int) {
                    }

                    override fun onBroadcastStopFailed(reason: Int) {
                    }

                    override fun onPlaybackStarted(reason: Int, broadcastId: Int) {
                        launch { trySend(Unit) }
                    }

                    override fun onPlaybackStopped(reason: Int, broadcastId: Int) {
                    }

                    override fun onBroadcastUpdated(reason: Int, broadcastId: Int) {}

                    override fun onBroadcastUpdateFailed(reason: Int, broadcastId: Int) {}

                    override fun onBroadcastMetadataChanged(
                        broadcastId: Int,
                        metadata: BluetoothLeBroadcastMetadata
                    ) {}
                }
            registerServiceCallBack(
                ConcurrentUtils.DIRECT_EXECUTOR,
                listener,
            )
            awaitClose { unregisterServiceCallBack(listener) }
        }
            .buffer(capacity = Channel.CONFLATED)
+10 −0
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ interface AudioSharingRepository {
    /** The headset groupId to volume map during audio sharing. */
    val volumeMap: StateFlow<GroupIdToVolumes>

    suspend fun audioSharingAvailable(): Boolean

    /** Set the volume of secondary headset during audio sharing. */
    suspend fun setSecondaryVolume(
        @IntRange(from = AUDIO_SHARING_VOLUME_MIN.toLong(), to = AUDIO_SHARING_VOLUME_MAX.toLong())
@@ -216,6 +218,12 @@ class AudioSharingRepositoryImpl(
        }
            .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), emptyMap())

    override suspend fun audioSharingAvailable(): Boolean {
        return withContext(backgroundCoroutineContext) {
            BluetoothUtils.isAudioSharingEnabled()
        }
    }

    override suspend fun setSecondaryVolume(
        @IntRange(from = AUDIO_SHARING_VOLUME_MIN.toLong(), to = AUDIO_SHARING_VOLUME_MAX.toLong())
        volume: Int
@@ -262,6 +270,8 @@ class AudioSharingRepositoryEmptyImpl : AudioSharingRepository {
        MutableStateFlow(BluetoothCsipSetCoordinator.GROUP_ID_INVALID)
    override val volumeMap: StateFlow<GroupIdToVolumes> = MutableStateFlow(emptyMap())

    override suspend fun audioSharingAvailable(): Boolean = false

    override suspend fun setSecondaryVolume(
        @IntRange(from = AUDIO_SHARING_VOLUME_MIN.toLong(), to = AUDIO_SHARING_VOLUME_MAX.toLong())
        volume: Int
+2 −2
Original line number Diff line number Diff line
@@ -425,8 +425,8 @@ filegroup {
        "tests/src/**/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt",
        "tests/src/**/systemui/shared/system/RemoteTransitionTest.java",
        "tests/src/**/systemui/navigationbar/NavigationBarControllerImplTest.java",
        "tests/src/**/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt",
        "tests/src/**/systemui/bluetooth/qsdialog/DeviceItemActionInteractorTest.kt",
        "tests/src/**/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt",
        "tests/src/**/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt",
        "tests/src/**/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt",
        "tests/src/**/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivityTest.kt",
        "tests/src/**/systemui/notetask/shortcut/LaunchNoteTaskActivityTest.kt",
+115 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?><!--
  ~ 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.
  -->

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root"
    style="@style/Widget.SliceView.Panel"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ImageView android:id="@+id/icon"
        android:layout_width="28dp"
        android:layout_height="28dp"
        android:src="@drawable/ic_bt_le_audio_sharing"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="20dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toTopOf="@id/title"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:gravity="center_vertical|center_horizontal"
        android:maxLines="1"
        android:ellipsize="end"
        android:text="@string/quick_settings_bluetooth_audio_sharing_dialog_title"
        android:textAppearance="@style/TextAppearance.Dialog.Title"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toTopOf="@id/subtitle"
        app:layout_constraintTop_toBottomOf="@id/icon" />

    <TextView
        android:id="@+id/subtitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:gravity="center_vertical|center_horizontal"
        android:ellipsize="end"
        android:maxLines="2"
        android:textAppearance="@style/TextAppearance.Dialog.Body.Message"
        android:textFontWeight="500"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toTopOf="@id/message"
        app:layout_constraintTop_toBottomOf="@id/title" />

    <TextView
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:gravity="center_vertical|center_horizontal"
        android:ellipsize="end"
        android:maxLines="2"
        android:text="@string/quick_settings_bluetooth_audio_sharing_dialog_message"
        android:textAppearance="@style/TextAppearance.Dialog.Body.Message"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toTopOf="@id/share_audio_button"
        app:layout_constraintTop_toBottomOf="@id/subtitle" />

    <Button
        android:id="@+id/share_audio_button"
        style="@style/SettingsLibActionButton"
        android:textColor="?androidprv:attr/textColorOnAccent"
        android:background="@drawable/audio_sharing_rounded_bg_ripple"
        android:layout_marginBottom="4dp"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:minHeight="64dp"
        android:contentDescription="@string/accessibility_bluetooth_device_settings_see_all"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/message"
        app:layout_constraintBottom_toTopOf="@+id/switch_active_button"
        android:text="@string/quick_settings_bluetooth_audio_sharing_button"
        android:maxLines="2" />

    <Button
        android:id="@+id/switch_active_button"
        style="@style/SettingsLibActionButton"
        android:textColor="?androidprv:attr/textColorOnAccent"
        android:background="@drawable/audio_sharing_rounded_bg_ripple"
        android:layout_marginBottom="20dp"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:minHeight="64dp"
        android:contentDescription="@string/accessibility_bluetooth_device_settings_pair_new_device"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/share_audio_button"
        app:layout_constraintBottom_toBottomOf="parent"
        android:maxLines="2" />
</androidx.constraintlayout.widget.ConstraintLayout>
 No newline at end of file
+8 −0
Original line number Diff line number Diff line
@@ -765,6 +765,14 @@
    <string name="quick_settings_bluetooth_audio_sharing_button_sharing">Sharing audio</string>
    <!-- QuickSettings: Bluetooth dialog audio sharing button text accessibility label. Used as part of the string "Double tap to enter audio sharing settings". [CHAR LIMIT=50]-->
    <string name="quick_settings_bluetooth_audio_sharing_button_accessibility">enter audio sharing settings</string>
    <!-- QuickSettings: Bluetooth audio sharing dialog message. [CHAR LIMIT=NONE]-->
    <string name="quick_settings_bluetooth_audio_sharing_dialog_message">This device\'s music and videos will play on both pairs of headphones</string>
    <!-- QuickSettings: Bluetooth audio sharing dialog title. [CHAR LIMIT=NONE]-->
    <string name="quick_settings_bluetooth_audio_sharing_dialog_title">Share your audio</string>
    <!-- QuickSettings: Bluetooth audio sharing dialog subtitle. [CHAR LIMIT=NONE]-->
    <string name="quick_settings_bluetooth_audio_sharing_dialog_subtitle"><xliff:g id="available_device_name" example="device 1">%1$s</xliff:g> and <xliff:g id="active_device_name" example="device 2">%2$s</xliff:g></string>
    <!-- QuickSettings: Bluetooth audio sharing dialog button text. [CHAR LIMIT=NONE]-->
    <string name="quick_settings_bluetooth_audio_sharing_dialog_switch_to_button">Switch to <xliff:g id="available_device_name" example="device 1">%1$s</xliff:g></string>

    <!-- QuickSettings: Bluetooth secondary label for the battery level of a connected device [CHAR LIMIT=20]-->
    <string name="quick_settings_bluetooth_secondary_label_battery_level"><xliff:g id="battery_level_as_percentage">%s</xliff:g> battery</string>
Loading