[LE Audio] Broadcast Sink UI
- Add dialog for Broadcast and find broadcast source
- Add Activity for find broadcast source
Bug: 228274114
Test: Manual test
Change-Id: I830efc3514fc42aaa4e53f491ed3a7459bd9bb41
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d927073..d2e33d5 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -4081,6 +4081,38 @@
android:value="true" />
</activity>
+ <activity
+ android:name="Settings$BluetoothBroadcastActivity"
+ android:exported="true"
+ android:theme="@style/Theme.AlertDialog.SimConfirmDialog"
+ android:permission="android.permission.BLUETOOTH_CONNECT"
+ android:configChanges="orientation|keyboardHidden|screenSize">
+ <intent-filter android:priority="1">
+ <action android:name="android.settings.MEDIA_BROADCAST_DIALOG" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.bluetooth.BluetoothBroadcastsDialog" />
+ <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+ android:value="true" />
+ </activity>
+
+ <activity
+ android:name="Settings$BluetoothFindBroadcastsActivity"
+ android:label="@string/bluetooth_find_broadcast_title"
+ android:exported="true"
+ android:permission="android.permission.BLUETOOTH_CONNECT"
+ android:configChanges="orientation|keyboardHidden|screenSize">
+ <intent-filter android:priority="1">
+ <action android:name="android.settings.BLUTOOTH_FIND_BROADCASTS_ACTIVITY" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.bluetooth.BluetoothFindBroadcastsFragment" />
+ <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+ android:value="true" />
+ </activity>
+
<activity android:name=".panel.SettingsPanelActivity"
android:label="@string/settings_panel_title"
android:theme="@style/Theme.Panel"
diff --git a/res/drawable/broadcast_button_outline.xml b/res/drawable/broadcast_button_outline.xml
new file mode 100644
index 0000000..6609915
--- /dev/null
+++ b/res/drawable/broadcast_button_outline.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 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.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:insetTop="6dp"
+ android:insetBottom="6dp">
+ <ripple android:color="?android:attr/colorControlHighlight">
+ <item android:id="@android:id/mask">
+ <shape android:shape="rectangle">
+ <solid android:color="@android:color/white"/>
+ <corners android:radius="24dp"/>
+ </shape>
+ </item>
+ <item>
+ <shape android:shape="rectangle">
+ <corners android:radius="24dp"/>
+ <solid android:color="@android:color/transparent"/>
+ <stroke android:color="?androidprv:attr/colorAccentPrimaryVariant"
+ android:width="1dp"
+ />
+ <padding android:left="16dp"
+ android:top="8dp"
+ android:right="16dp"
+ android:bottom="8dp"/>
+ </shape>
+ </item>
+ </ripple>
+</inset>
diff --git a/res/layout/bluetooth_broadcast_entity_header.xml b/res/layout/bluetooth_broadcast_entity_header.xml
new file mode 100644
index 0000000..cc18d94
--- /dev/null
+++ b/res/layout/bluetooth_broadcast_entity_header.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/entity_header"
+ style="@style/EntityHeader"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/entity_header_title"
+ style="@style/TextAppearance.EntityHeaderTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="false"
+ android:ellipsize="marquee"
+ android:textDirection="locale"/>
+
+ <TextView
+ android:id="@+id/entity_header_summary"
+ style="@style/TextAppearance.EntityHeaderSummary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/bluetooth_find_broadcast_header_top_margin"
+ android:singleLine="false"
+ android:ellipsize="marquee"
+ android:textDirection="locale"/>
+
+ <Button
+ android:id="@+id/button_find_broadcast"
+ android:layout_width="@dimen/bluetooth_find_broadcast_button_one_size"
+ android:layout_height="wrap_content"
+ android:text="@string/bluetooth_find_broadcast"
+ android:clickable="true"
+ style="@style/BroadcastActionButton" />
+
+ <LinearLayout
+ android:id="@+id/button_broadcast_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="horizontal" >
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <Button
+ android:id="@+id/button_leave_broadcast"
+ android:layout_width="@dimen/bluetooth_find_broadcast_button_two_size"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/bluetooth_find_broadcast_button_leave"
+ android:clickable="true"
+ style="@style/BroadcastActionButton" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/bluetooth_find_broadcast_button_start_margin">
+ <Button
+ android:id="@+id/button_scan_qr_code"
+ android:layout_width="@dimen/bluetooth_find_broadcast_button_two_size"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/bluetooth_find_broadcast_button_scan"
+ android:clickable="true"
+ style="@style/BroadcastActionButton" />
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <android.widget.ProgressBar
+ android:id="@+id/progressBar"
+ style="?android:attr/progressBarStyleHorizontal"
+ android:layout_width="@dimen/bluetooth_find_broadcast_progress_width"
+ android:layout_height="@dimen/bluetooth_find_broadcast_progress_height"
+ android:layout_marginTop="@dimen/bluetooth_find_broadcast_progress_margin_top"
+ android:progressDrawable="@drawable/color_bar_progress"/>
+</LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8a59da2..7eec0db 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -406,6 +406,15 @@
<dimen name="le_bluetooth_summary_start_margin">20dp</dimen>
<dimen name="le_bluetooth_summary_padding">1.5dp</dimen>
+ <!-- Header layout of bluetooth find broadcast page -->
+ <dimen name="bluetooth_find_broadcast_button_one_size">220dp</dimen>
+ <dimen name="bluetooth_find_broadcast_button_two_size">150dp</dimen>
+ <dimen name="bluetooth_find_broadcast_button_start_margin">16dp</dimen>
+ <dimen name="bluetooth_find_broadcast_header_top_margin">4dp</dimen>
+ <dimen name="bluetooth_find_broadcast_progress_width">155dp</dimen>
+ <dimen name="bluetooth_find_broadcast_progress_height">4dp</dimen>
+ <dimen name="bluetooth_find_broadcast_progress_margin_top">8dp</dimen>
+
<!-- Developer option bluetooth settings dialog -->
<dimen name="developer_option_dialog_margin_start">8dp</dimen>
<dimen name="developer_option_dialog_margin_top">8dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 905f036..6b5892d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -14103,4 +14103,22 @@
<string name="ingress_rate_limit_dialog_title">Configure network download rate limit</string>
<!-- Developer Settings: Dialog ListPreference option to disable network bandwidth ingress rate limit [CHAR LIMIT=none] -->
<string name="ingress_rate_limit_no_limit_entry">No limit</string>
+
+ <!-- BT LE Audio Device: Media Broadcast -->
+ <!-- The title of the Media Broadcast Dialog [CHAR LIMIT=none] -->
+ <string name="bluetooth_broadcast_dialog_title">Broadcast</string>
+ <!-- The message of the Media Broadcast Dialog for finding broadcast [CHAR LIMIT=none] -->
+ <string name="bluetooth_broadcast_dialog_find_message">Listen to broadcasts that are playing near you</string>
+ <!-- The message of the Media Broadcast Dialog for broadcast [CHAR LIMIT=none] -->
+ <string name="bluetooth_broadcast_dialog_broadcast_message">Broadcast media to devices near you, or listen to someone else’s broadcast</string>
+ <!-- The title of the Media Find Broadcast activity [CHAR LIMIT=none] -->
+ <string name="bluetooth_find_broadcast_title">Broadcasts</string>
+ <!-- The summary of the Media Find Broadcast activity [CHAR LIMIT=none] -->
+ <string name="bluetooth_find_broadcast_summary">Listening to</string>
+ <!-- The Button of the action to find broadcasts [CHAR LIMIT=none] -->
+ <string name="bluetooth_find_broadcast">Find broadcasts</string>
+ <!-- The Button of the action to leave the broadcast [CHAR LIMIT=none] -->
+ <string name="bluetooth_find_broadcast_button_leave">Leave broadcast</string>
+ <!-- The Button of the action to scan QR code [CHAR LIMIT=none] -->
+ <string name="bluetooth_find_broadcast_button_scan">Scan QR code</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8e91a9e..5e4e5a4 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -953,4 +953,15 @@
<item name="android:background">@drawable/data_bytes_editor_spinner_background</item>
<item name="android:dropDownVerticalOffset">36dp</item>
</style>
+
+ <style name="BroadcastActionButton" parent="@android:style/Widget.Material.Button">
+ <item name="android:background">@drawable/broadcast_button_outline</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:textSize">14sp</item>
+ <item name="android:lineHeight">20sp</item>
+ <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
+ <item name="android:stateListAnimator">@null</item>
+ <item name="android:minWidth">0dp</item>
+ <item name="android:textAllCaps">false</item>
+ </style>
</resources>
diff --git a/res/xml/bluetooth_find_broadcasts_fragment.xml b/res/xml/bluetooth_find_broadcasts_fragment.xml
new file mode 100644
index 0000000..a564ac9
--- /dev/null
+++ b/res/xml/bluetooth_find_broadcasts_fragment.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 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.
+ -->
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:title="@string/bluetooth_find_broadcast_title">
+
+ <com.android.settingslib.widget.LayoutPreference
+ android:key="bluetooth_find_broadcast_header"
+ android:layout="@layout/bluetooth_broadcast_entity_header"
+ android:selectable="false"
+ settings:allowDividerBelow="true"
+ settings:searchable="false" />
+
+ <PreferenceCategory
+ android:key="broadcast_source_list"
+ android:layout="@layout/preference_category_no_label"/>
+
+</PreferenceScreen>
+
+
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 9282d92..f294e7d 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -360,6 +360,8 @@
public static class WebViewAppPickerActivity extends SettingsActivity { /* empty */ }
public static class AdvancedConnectedDeviceActivity extends SettingsActivity { /* empty */ }
public static class BluetoothDeviceDetailActivity extends SettingsActivity { /* empty */ }
+ public static class BluetoothBroadcastActivity extends SettingsActivity { /* empty */ }
+ public static class BluetoothFindBroadcastsActivity 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/bluetooth/BluetoothBroadcastDialog.java b/src/com/android/settings/bluetooth/BluetoothBroadcastDialog.java
new file mode 100644
index 0000000..c743653
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothBroadcastDialog.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 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.bluetooth;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+import java.util.ArrayList;
+
+/**
+ * This Dialog allowed users to do some actions for broadcast media or find the
+ * nearby broadcast sources.
+ */
+public class BluetoothBroadcastDialog extends InstrumentedDialogFragment {
+
+ private static final String TAG = "BTBroadcastsDialog";
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setShowsDialog(true);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Context context = getActivity();
+ final boolean isMediaPlaying = isMediaPlaying();
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(isMediaPlaying ? R.string.bluetooth_find_broadcast
+ : R.string.bluetooth_broadcast_dialog_title);
+ builder.setMessage(isMediaPlaying ? R.string.bluetooth_broadcast_dialog_find_message
+ : R.string.bluetooth_broadcast_dialog_broadcast_message);
+
+ ArrayList<String> optionList = new ArrayList<String>();
+ if (!isMediaPlaying) {
+ optionList.add(context.getString(R.string.bluetooth_broadcast_dialog_title));
+ }
+ optionList.add(context.getString(R.string.bluetooth_find_broadcast));
+ optionList.add(context.getString(android.R.string.cancel));
+
+ View content = LayoutInflater.from(context).inflate(
+ R.layout.sim_confirm_dialog_multiple_enabled_profiles_supported, null);
+
+ if (content != null) {
+ Log.i(TAG, "list =" + optionList.toString());
+
+ final ArrayAdapter<String> arrayAdapterItems = new ArrayAdapter<String>(
+ context,
+ R.layout.sim_confirm_dialog_item_multiple_enabled_profiles_supported,
+ optionList);
+ final ListView lvItems = content.findViewById(R.id.carrier_list);
+ if (lvItems != null) {
+ lvItems.setVisibility(View.VISIBLE);
+ lvItems.setAdapter(arrayAdapterItems);
+ lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position,
+ long id) {
+ Log.i(TAG, "list onClick =" + position);
+ Log.i(TAG, "list item =" + optionList.get(position));
+
+ if (position == optionList.size() - 1) {
+ // The last position in the options is the Cancel button. So when
+ // the user clicks the button, we do nothing but dismiss the dialog.
+ dismiss();
+ } else {
+ if (optionList.get(position).equals(
+ context.getString(R.string.bluetooth_find_broadcast))) {
+ launchFindBroadcastsActivity();
+ } else {
+ launchMediaOutputBroadcastDialog();
+ }
+ }
+ }
+ });
+ }
+ builder.setView(content);
+ } else {
+ Log.i(TAG, "optionList is empty");
+ }
+
+ AlertDialog dialog = builder.create();
+ dialog.setCanceledOnTouchOutside(false);
+ return dialog;
+ }
+
+ private boolean isMediaPlaying() {
+ return true;
+ }
+
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ //TODO(b/228255796) : add new enum for find broadcast fragment
+ return SettingsEnums.PAGE_UNKNOWN;
+ }
+
+ private void launchFindBroadcastsActivity() {
+
+ }
+
+ private void launchMediaOutputBroadcastDialog() {
+
+ }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragment.java b/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragment.java
new file mode 100644
index 0000000..f251db5
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragment.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2022 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.bluetooth;
+
+import static android.bluetooth.BluetoothDevice.BOND_NONE;
+import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
+
+import android.app.settings.SettingsEnums;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.RestrictedDashboardFragment;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This fragment allowed users to find the nearby broadcast sources.
+ */
+public class BluetoothFindBroadcastsFragment extends RestrictedDashboardFragment {
+
+ private static final String TAG = "BTFindBroadcastsFrg";
+
+ public static final String KEY_DEVICE_ADDRESS = "device_address";
+
+ public static final String PREF_KEY_BROADCAST_SOURCE = "broadcast_source";
+
+ @VisibleForTesting
+ String mDeviceAddress;
+ @VisibleForTesting
+ LocalBluetoothManager mManager;
+ @VisibleForTesting
+ CachedBluetoothDevice mCachedDevice;
+
+ public BluetoothFindBroadcastsFragment() {
+ super(DISALLOW_CONFIG_BLUETOOTH);
+ }
+
+ @VisibleForTesting
+ LocalBluetoothManager getLocalBluetoothManager(Context context) {
+ return Utils.getLocalBtManager(context);
+ }
+
+ @VisibleForTesting
+ CachedBluetoothDevice getCachedDevice(String deviceAddress) {
+ BluetoothDevice remoteDevice =
+ mManager.getBluetoothAdapter().getRemoteDevice(deviceAddress);
+ return mManager.getCachedDeviceManager().findDevice(remoteDevice);
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ mDeviceAddress = getArguments().getString(KEY_DEVICE_ADDRESS);
+ mManager = getLocalBluetoothManager(context);
+ mCachedDevice = getCachedDevice(mDeviceAddress);
+ super.onAttach(context);
+ if (mCachedDevice == null) {
+ //Close this page if device is null with invalid device mac address
+ Log.w(TAG, "onAttach() CachedDevice is null!");
+ finish();
+ return;
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ finishFragmentIfNecessary();
+ }
+
+ @VisibleForTesting
+ void finishFragmentIfNecessary() {
+ if (mCachedDevice.getBondState() == BOND_NONE) {
+ finish();
+ return;
+ }
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ //TODO(b/228255796) : add new enum for find broadcast fragment
+ return SettingsEnums.PAGE_UNKNOWN;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.bluetooth_find_broadcasts_fragment;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ ArrayList<AbstractPreferenceController> controllers = new ArrayList<>();
+
+ if (mCachedDevice != null) {
+ Lifecycle lifecycle = getSettingsLifecycle();
+ controllers.add(new BluetoothFindBroadcastsHeaderController(context, this,
+ mCachedDevice, lifecycle, mManager));
+ }
+ return controllers;
+ }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothFindBroadcastsHeaderController.java b/src/com/android/settings/bluetooth/BluetoothFindBroadcastsHeaderController.java
new file mode 100644
index 0000000..dfdcae0
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothFindBroadcastsHeaderController.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2022 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.bluetooth;
+
+import android.content.Context;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
+
+/**
+ * This class adds a header to display the action button for joining the broadcast session
+ * by scanning QR code and leaving the broadcast session
+ */
+public class BluetoothFindBroadcastsHeaderController extends BluetoothDetailsController {
+ private static final String TAG = "BtFindBroadcastCtrl";
+
+ private static final String KEY_BROADCAST_HEADER = "bluetooth_find_broadcast_header";
+ private static final String KEY_BROADCAST_SOURCE_LIST = "broadcast_source_list";
+
+ LayoutPreference mLayoutPreference;
+ PreferenceCategory mBroadcastSourceList;
+ TextView mTitle;
+ TextView mSummary;
+ Button mBtnFindBroadcast;
+ LinearLayout mBtnBroadcastLayout;
+ Button mBtnLeaveBroadcast;
+ Button mBtnScanQrCode;
+
+ public BluetoothFindBroadcastsHeaderController(Context context,
+ PreferenceFragmentCompat fragment, CachedBluetoothDevice device, Lifecycle lifecycle,
+ LocalBluetoothManager bluetoothManager) {
+ super(context, fragment, device, lifecycle);
+ }
+
+ @Override
+ protected void init(PreferenceScreen screen) {
+ mLayoutPreference = screen.findPreference(KEY_BROADCAST_HEADER);
+ mBroadcastSourceList = screen.findPreference(KEY_BROADCAST_SOURCE_LIST);
+
+ refresh();
+ }
+
+ @Override
+ protected void refresh() {
+ if (mLayoutPreference == null || mCachedDevice == null) {
+ return;
+ }
+
+ mTitle = mLayoutPreference.findViewById(R.id.entity_header_title);
+ mTitle.setText(mCachedDevice.getName());
+ mSummary = mLayoutPreference.findViewById(R.id.entity_header_summary);
+ mSummary.setText("");
+
+ mBtnFindBroadcast = mLayoutPreference.findViewById(R.id.button_find_broadcast);
+ mBtnFindBroadcast.setOnClickListener(v -> scanBroadcastSource());
+ mBtnBroadcastLayout = mLayoutPreference.findViewById(R.id.button_broadcast_layout);
+ mBtnLeaveBroadcast = mLayoutPreference.findViewById(R.id.button_leave_broadcast);
+ mBtnLeaveBroadcast.setOnClickListener(v -> leaveBroadcastSession());
+ mBtnScanQrCode = mLayoutPreference.findViewById(R.id.button_scan_qr_code);
+ mBtnScanQrCode.setOnClickListener(v -> launchQrCodeScanner());
+
+ updateHeaderLayout();
+ }
+
+ private boolean isBroadcastSourceExist() {
+ return mBroadcastSourceList.getPreferenceCount() > 0;
+ }
+
+ private void updateHeaderLayout() {
+ if (isBroadcastSourceExist()) {
+ mBtnFindBroadcast.setVisibility(View.GONE);
+ mBtnBroadcastLayout.setVisibility(View.VISIBLE);
+ } else {
+ mBtnFindBroadcast.setVisibility(View.VISIBLE);
+ mBtnBroadcastLayout.setVisibility(View.GONE);
+ }
+ }
+
+ private void scanBroadcastSource() {
+ // TODO(b/228258236) : Call the LocalBluetoothLeBroadcastAssistant
+ // to start searching for source
+ }
+
+ private void leaveBroadcastSession() {
+ // TODO(b/228258236) : Call the LocalBluetoothLeBroadcastAssistant
+ // to leave the broadcast session
+ }
+
+ private void launchQrCodeScanner() {
+ // TODO(b/228259065) : Launch the QR code scanner page by intent
+ }
+
+ @Override
+ public void onDeviceAttributesChanged() {
+ if (mCachedDevice != null) {
+ refresh();
+ }
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BROADCAST_HEADER;
+ }
+}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index b11ce01..81de756 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -71,7 +71,9 @@
import com.android.settings.biometrics.combination.CombinedBiometricSettings;
import com.android.settings.biometrics.face.FaceSettings;
import com.android.settings.biometrics.fingerprint.FingerprintSettings;
+import com.android.settings.bluetooth.BluetoothBroadcastDialog;
import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
+import com.android.settings.bluetooth.BluetoothFindBroadcastsFragment;
import com.android.settings.bluetooth.BluetoothPairingDetail;
import com.android.settings.bugreporthandler.BugReportHandlerPicker;
import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
@@ -317,6 +319,8 @@
WebViewAppPicker.class.getName(),
LockscreenDashboardFragment.class.getName(),
BluetoothDeviceDetailsFragment.class.getName(),
+ BluetoothBroadcastDialog.class.getName(),
+ BluetoothFindBroadcastsFragment.class.getName(),
DataUsageList.class.getName(),
ToggleBackupSettingFragment.class.getName(),
PreviouslyConnectedDeviceDashboardFragment.class.getName(),