[Audiosharing] Create confirmation to join audio.

Bug: 305620450
Test: manual
Change-Id: I7bb8ed290808115cb76b59f3bfdc52f09806034d
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8c6b84a..b956f67 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -4604,6 +4604,22 @@
         </activity>
 
         <activity
+            android:name="Settings$AudioStreamConfirmDialogActivity"
+            android:exported="true"
+            android:theme="@style/Transparent"
+            android:permission="android.permission.BLUETOOTH_CONNECT"
+            android:configChanges="orientation|keyboardHidden|screenSize">
+            <intent-filter android:priority="1">
+                <action android:name="android.settings.AUDIO_STREAM_DIALOG" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamConfirmDialog" />
+            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+                android:value="true" />
+        </activity>
+
+        <activity
             android:name=".Settings$PreviouslyConnectedDeviceActivity"
             android:label="@string/connected_device_saved_title"
             android:exported="true"
diff --git a/res/xml/bluetooth_audio_streams_dialog.xml b/res/xml/bluetooth_audio_streams_dialog.xml
index afc5055..502e55a 100644
--- a/res/xml/bluetooth_audio_streams_dialog.xml
+++ b/res/xml/bluetooth_audio_streams_dialog.xml
@@ -78,14 +78,14 @@
                 android:layout_height="wrap_content"
                 android:layout_marginLeft="16dp"
                 android:layout_weight="1"
-                android:visibility="gone"/>
+                android:visibility="invisible"/>
             <Button
                 android:id="@+id/right_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
                 android:layout_marginRight="16dp"
-                android:visibility="gone"/>
+                android:visibility="invisible"/>
         </LinearLayout>
 
     </LinearLayout>
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 3e48a9c..52f5e5b 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -399,6 +399,7 @@
     public static class StylusUsiDetailsActivity extends SettingsActivity { /* empty */ }
     public static class BluetoothBroadcastActivity extends SettingsActivity { /* empty */ }
     public static class BluetoothFindBroadcastsActivity extends SettingsActivity { /* empty */ }
+    public static class AudioStreamConfirmDialogActivity extends SettingsActivity { /* empty */ }
     public static class WifiCallingDisclaimerActivity extends SettingsActivity { /* empty */ }
     public static class MobileNetworkListActivity extends SettingsActivity {}
     public static class PowerMenuSettingsActivity extends SettingsActivity {}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialog.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialog.java
new file mode 100644
index 0000000..5981c9e
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialog.java
@@ -0,0 +1,128 @@
+/*
+ * 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.audiostreams;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.bluetooth.BluetoothLeBroadcastMetadata;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.settings.R;
+import com.android.settings.bluetooth.Utils;
+import com.android.settings.connecteddevice.audiosharing.audiostreams.qrcode.QrCodeScanModeFragment;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settingslib.bluetooth.BluetoothLeBroadcastMetadataExt;
+
+import com.google.common.base.Strings;
+
+public class AudioStreamConfirmDialog extends InstrumentedDialogFragment {
+    public static final String KEY_BROADCAST_METADATA = "key_broadcast_metadata";
+    private static final String TAG = "AudioStreamConfirmDialog";
+    private Activity mActivity;
+    private String mBroadcastMetadataStr;
+    private BluetoothLeBroadcastMetadata mBroadcastMetadata;
+    private boolean mIsRequestValid = false;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setShowsDialog(true);
+        mActivity = getActivity();
+        if (mActivity == null) {
+            Log.w(TAG, "onCreate() mActivity is null!");
+            return;
+        }
+        mBroadcastMetadataStr =
+                mActivity.getIntent().getStringExtra(QrCodeScanModeFragment.KEY_BROADCAST_METADATA);
+        if (Strings.isNullOrEmpty(mBroadcastMetadataStr)) {
+            Log.w(TAG, "onCreate() mBroadcastMetadataStr is null or empty!");
+            return;
+        }
+        mBroadcastMetadata =
+                BluetoothLeBroadcastMetadataExt.INSTANCE.convertToBroadcastMetadata(
+                        mBroadcastMetadataStr);
+        if (mBroadcastMetadata == null) {
+            Log.w(TAG, "onCreate() mBroadcastMetadata is null!");
+        } else {
+            // Warm up LE_AUDIO_BROADCAST_ASSISTANT service
+            Utils.getLocalBluetoothManager(mActivity);
+            mIsRequestValid = true;
+        }
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        return mIsRequestValid ? getConfirmDialog() : getErrorDialog();
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO(chelseahao): update metrics id
+        return 0;
+    }
+
+    private Dialog getConfirmDialog() {
+        return new AudioStreamsDialogFragment.DialogBuilder(mActivity)
+                .setTitle("Listen to audio stream")
+                .setSubTitle1(mBroadcastMetadata.getBroadcastName())
+                .setSubTitle2(
+                        "The audio stream will play on the active LE audio device. Use this device"
+                                + " to control the volume.")
+                .setLeftButtonText("Cancel")
+                .setLeftButtonOnClickListener(
+                        unused -> {
+                            dismiss();
+                            mActivity.finish();
+                        })
+                .setRightButtonText("Listen")
+                .setRightButtonOnClickListener(
+                        unused -> {
+                            launchAudioStreamsActivity();
+                            dismiss();
+                            mActivity.finish();
+                        })
+                .build();
+    }
+
+    private Dialog getErrorDialog() {
+        return new AudioStreamsDialogFragment.DialogBuilder(mActivity)
+                .setTitle("Can't listen to audio stream")
+                .setSubTitle1("Can't play this audio stream. Learn more")
+                .setRightButtonText("Close")
+                .setRightButtonOnClickListener(
+                        unused -> {
+                            dismiss();
+                            mActivity.finish();
+                        })
+                .build();
+    }
+
+    private void launchAudioStreamsActivity() {
+        Bundle bundle = new Bundle();
+        bundle.putString(KEY_BROADCAST_METADATA, mBroadcastMetadataStr);
+
+        new SubSettingLauncher(mActivity)
+                .setTitleRes(R.string.bluetooth_find_broadcast_title)
+                .setDestination(AudioStreamsDashboardFragment.class.getName())
+                .setArguments(bundle)
+                .setSourceMetricsCategory(SettingsEnums.PAGE_UNKNOWN)
+                .launch();
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java
index b5c71b6..bddbb61 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java
@@ -31,6 +31,8 @@
 import com.android.settingslib.bluetooth.BluetoothLeBroadcastMetadataExt;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 
+import com.google.common.base.Strings;
+
 public class AudioStreamsDashboardFragment extends DashboardFragment {
     private static final String TAG = "AudioStreamsDashboardFrag";
     private static final boolean DEBUG = BluetoothUtils.D;
@@ -72,6 +74,21 @@
         use(AudioStreamsScanQrCodeController.class).setFragment(this);
         mAudioStreamsProgressCategoryController = use(AudioStreamsProgressCategoryController.class);
         mAudioStreamsProgressCategoryController.setFragment(this);
+
+        if (getArguments() != null) {
+            String broadcastMetadataStr =
+                    getArguments().getString(AudioStreamConfirmDialog.KEY_BROADCAST_METADATA);
+            if (!Strings.isNullOrEmpty(broadcastMetadataStr)) {
+                BluetoothLeBroadcastMetadata broadcastMetadata =
+                        BluetoothLeBroadcastMetadataExt.INSTANCE.convertToBroadcastMetadata(
+                                broadcastMetadataStr);
+                if (broadcastMetadata == null) {
+                    Log.w(TAG, "onAttach() broadcastMetadata is null!");
+                } else {
+                    mAudioStreamsProgressCategoryController.setSourceFromQrCode(broadcastMetadata);
+                }
+            }
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 3433e12..b40b6bf 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -84,6 +84,7 @@
 import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
 import com.android.settings.connecteddevice.NfcAndPaymentFragment;
 import com.android.settings.connecteddevice.PreviouslyConnectedDeviceDashboardFragment;
+import com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamConfirmDialog;
 import com.android.settings.connecteddevice.stylus.StylusUsiDetailsFragment;
 import com.android.settings.connecteddevice.usb.UsbDetailsFragment;
 import com.android.settings.datausage.DataSaverSummary;
@@ -349,6 +350,7 @@
             DataUsageList.class.getName(),
             ToggleBackupSettingFragment.class.getName(),
             PreviouslyConnectedDeviceDashboardFragment.class.getName(),
+            AudioStreamConfirmDialog.class.getName(),
             BatterySaverScheduleSettings.class.getName(),
             MobileNetworkListFragment.class.getName(),
             PowerMenuSettings.class.getName(),