[LE] Launch the dialog for the user to broadcast or find broadcast

- Launch the broadcast dialog from entry point in Media Volume Slice

    - Fix the broadcast dialog to follow the dialog style

    - Start broadcast and launch the MediaOutputBroadcastDialog from
      broadcast dialog

Bug: 229577518
Test: manual test
Change-Id: I1329b3f35b03afc441142494df883ae17f373656
This commit is contained in:
changbetty
2022-04-28 15:49:49 +00:00
parent 71e03076cd
commit f31b5769d7
5 changed files with 132 additions and 76 deletions

View File

@@ -4124,7 +4124,7 @@
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS" <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.bluetooth.BluetoothBroadcastsDialog" /> android:value="com.android.settings.bluetooth.BluetoothBroadcastDialog" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED" <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" /> android:value="true" />
</activity> </activity>

View File

@@ -14125,6 +14125,8 @@
<!-- BT LE Audio Device: Media Broadcast --> <!-- BT LE Audio Device: Media Broadcast -->
<!-- The title of the Media Broadcast Dialog [CHAR LIMIT=none] --> <!-- The title of the Media Broadcast Dialog [CHAR LIMIT=none] -->
<string name="bluetooth_broadcast_dialog_title">Broadcast</string> <string name="bluetooth_broadcast_dialog_title">Broadcast</string>
<!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, switch to others app. -->
<string name="bluetooth_broadcast_dialog_broadcast_app">Broadcast <xliff:g id="currentApp" example="App Name 2">%1$s</xliff:g></string>
<!-- The message of the Media Broadcast Dialog for finding broadcast [CHAR LIMIT=none] --> <!-- 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> <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] --> <!-- The message of the Media Broadcast Dialog for broadcast [CHAR LIMIT=none] -->

View File

@@ -19,105 +19,93 @@ package com.android.settings.bluetooth;
import android.app.Dialog; import android.app.Dialog;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.AdapterView; import android.widget.Button;
import android.widget.ArrayAdapter; import android.widget.TextView;
import android.widget.ListView;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import java.util.ArrayList; import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.media.MediaOutputConstants;
/** /**
* This Dialog allowed users to do some actions for broadcast media or find the * This Dialog allowed users to do some actions for broadcast media or find the
* nearby broadcast sources. * nearby broadcast sources.
*/ */
public class BluetoothBroadcastDialog extends InstrumentedDialogFragment { public class BluetoothBroadcastDialog extends InstrumentedDialogFragment {
public static final String KEY_APP_LABEL = "app_label";
public static final String KEY_DEVICE_ADDRESS =
BluetoothFindBroadcastsFragment.KEY_DEVICE_ADDRESS;
private static final String TAG = "BTBroadcastsDialog"; private static final String TAG = "BTBroadcastsDialog";
private static final CharSequence UNKNOWN_APP_LABEL = "unknown";
private Context mContext;
private CharSequence mCurrentAppLabel = UNKNOWN_APP_LABEL;
private String mDeviceAddress;
private LocalBluetoothManager mLocalBluetoothManager;
private AlertDialog mAlertDialog;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mContext = getActivity();
mCurrentAppLabel = getActivity().getIntent().getCharSequenceExtra(KEY_APP_LABEL);
mDeviceAddress = getActivity().getIntent().getStringExtra(KEY_DEVICE_ADDRESS);
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
setShowsDialog(true); setShowsDialog(true);
} }
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
final Context context = getActivity(); View layout = View.inflate(mContext,
final boolean isMediaPlaying = isMediaPlaying(); com.android.settingslib.R.layout.broadcast_dialog, null);
final AlertDialog.Builder builder = new AlertDialog.Builder(context); TextView title = layout.findViewById(com.android.settingslib.R.id.dialog_title);
builder.setTitle(isMediaPlaying ? R.string.bluetooth_find_broadcast TextView subTitle = layout.findViewById(com.android.settingslib.R.id.dialog_subtitle);
: R.string.bluetooth_broadcast_dialog_title); title.setText(mContext.getString(R.string.bluetooth_broadcast_dialog_title));
builder.setMessage(isMediaPlaying ? R.string.bluetooth_broadcast_dialog_find_message subTitle.setText(
: R.string.bluetooth_broadcast_dialog_broadcast_message); mContext.getString(R.string.bluetooth_broadcast_dialog_broadcast_message));
ArrayList<String> optionList = new ArrayList<String>(); Button broadcastBtn = layout.findViewById(com.android.settingslib.R.id.positive_btn);
if (!isMediaPlaying) { if (TextUtils.isEmpty(mCurrentAppLabel)) {
optionList.add(context.getString(R.string.bluetooth_broadcast_dialog_title)); broadcastBtn.setText(mContext.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 { } else {
Log.i(TAG, "optionList is empty"); broadcastBtn.setText(mContext.getString(
R.string.bluetooth_broadcast_dialog_broadcast_app,
String.valueOf(mCurrentAppLabel)));
} }
broadcastBtn.setOnClickListener((view) -> {
launchMediaOutputBroadcastDialog();
});
AlertDialog dialog = builder.create(); Button findBroadcastBtn = layout.findViewById(com.android.settingslib.R.id.negative_btn);
dialog.setCanceledOnTouchOutside(false); findBroadcastBtn.setText(mContext.getString(R.string.bluetooth_find_broadcast));
return dialog; findBroadcastBtn.setOnClickListener((view) -> {
launchFindBroadcastsActivity();
});
Button cancelBtn = layout.findViewById(com.android.settingslib.R.id.neutral_btn);
cancelBtn.setOnClickListener((view) -> {
dismiss();
getActivity().finish();
});
mAlertDialog = new AlertDialog.Builder(mContext,
com.android.settingslib.R.style.Theme_AlertDialog_SettingsLib)
.setView(layout)
.create();
return mAlertDialog;
} }
private boolean isMediaPlaying() {
return true;
}
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
@@ -130,10 +118,55 @@ public class BluetoothBroadcastDialog extends InstrumentedDialogFragment {
} }
private void launchFindBroadcastsActivity() { private void launchFindBroadcastsActivity() {
Bundle bundle = new Bundle();
bundle.putString(KEY_DEVICE_ADDRESS, mDeviceAddress);
new SubSettingLauncher(mContext)
.setTitleRes(R.string.bluetooth_find_broadcast_title)
.setDestination(BluetoothFindBroadcastsFragment.class.getName())
.setArguments(bundle)
.setSourceMetricsCategory(SettingsEnums.PAGE_UNKNOWN)
.launch();
dismissVolumePanel();
} }
private void launchMediaOutputBroadcastDialog() { private void launchMediaOutputBroadcastDialog() {
if (startBroadcast()) {
mContext.sendBroadcast(new Intent()
.setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME)
.setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG)
.putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME,
getActivity().getPackageName()));
dismissVolumePanel();
}
}
private LocalBluetoothLeBroadcast getLEAudioBroadcastProfile() {
if (mLocalBluetoothManager != null && mLocalBluetoothManager.getProfileManager() != null) {
LocalBluetoothLeBroadcast bluetoothLeBroadcast =
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
if (bluetoothLeBroadcast != null) {
return bluetoothLeBroadcast;
}
}
Log.d(TAG, "Can not get LE Audio Broadcast Profile");
return null;
}
private boolean startBroadcast() {
LocalBluetoothLeBroadcast btLeBroadcast = getLEAudioBroadcastProfile();
if (btLeBroadcast != null) {
btLeBroadcast.startBroadcast(String.valueOf(mCurrentAppLabel), null);
return true;
}
Log.d(TAG, "Can not broadcast successfully");
return false;
}
private void dismissVolumePanel() {
// Dismiss volume panel
mContext.sendBroadcast(new Intent()
.setPackage(MediaOutputConstants.SETTINGS_PACKAGE_NAME)
.setAction(MediaOutputConstants.ACTION_CLOSE_PANEL));
} }
} }

View File

@@ -161,7 +161,7 @@ public class MediaOutputIndicatorWorker extends SliceBackgroundWorker implements
return mLocalMediaManager.getCurrentConnectedDevice(); return mLocalMediaManager.getCurrentConnectedDevice();
} }
String getPackageName() { public String getPackageName() {
return mPackageName; return mPackageName;
} }

View File

@@ -31,9 +31,12 @@ import androidx.slice.builders.SliceAction;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.bluetooth.BluetoothBroadcastDialog;
import com.android.settings.media.MediaOutputIndicatorWorker; import com.android.settings.media.MediaOutputIndicatorWorker;
import com.android.settings.slices.CustomSliceRegistry; import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.media.BluetoothMediaDevice;
import com.android.settingslib.media.MediaDevice; import com.android.settingslib.media.MediaDevice;
import com.android.settingslib.media.MediaOutputConstants; import com.android.settingslib.media.MediaOutputConstants;
@@ -42,6 +45,9 @@ public class MediaVolumePreferenceController extends VolumeSeekBarPreferenceCont
private static final String KEY_MEDIA_VOLUME = "media_volume"; private static final String KEY_MEDIA_VOLUME = "media_volume";
private MediaOutputIndicatorWorker mWorker; private MediaOutputIndicatorWorker mWorker;
private MediaDevice mMediaDevice;
private static final String ACTION_LAUNCH_BROADCAST_DIALOG =
"android.settings.MEDIA_BROADCAST_DIALOG";
public MediaVolumePreferenceController(Context context) { public MediaVolumePreferenceController(Context context) {
super(context, KEY_MEDIA_VOLUME); super(context, KEY_MEDIA_VOLUME);
@@ -91,9 +97,9 @@ public class MediaVolumePreferenceController extends VolumeSeekBarPreferenceCont
} }
private boolean isConnectedBLEDevice() { private boolean isConnectedBLEDevice() {
final MediaDevice device = getWorker().getCurrentConnectedMediaDevice(); mMediaDevice = getWorker().getCurrentConnectedMediaDevice();
if (device != null) { if (mMediaDevice != null) {
return device.isBLEDevice(); return mMediaDevice.isBLEDevice();
} }
return false; return false;
} }
@@ -106,17 +112,32 @@ public class MediaVolumePreferenceController extends VolumeSeekBarPreferenceCont
} }
final Intent intent = new Intent(); final Intent intent = new Intent();
PendingIntent pi = null;
if (getWorker().isDeviceBroadcasting()) { if (getWorker().isDeviceBroadcasting()) {
intent.setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME); intent.setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME);
intent.setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG); intent.setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG);
intent.putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME, intent.putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME,
getWorker().getActiveLocalMediaController().getPackageName()); getWorker().getActiveLocalMediaController().getPackageName());
pi = PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
} else { } else {
// TODO(b/229577518) : Get the intent action of the Bluetooth Broadcast Dialog final CachedBluetoothDevice bluetoothDevice =
// for user to choose the action ((BluetoothMediaDevice) mMediaDevice).getCachedDevice();
if (bluetoothDevice == null) {
Log.d(TAG, "The bluetooth device is null");
return null;
}
intent.setAction(ACTION_LAUNCH_BROADCAST_DIALOG);
intent.putExtra(BluetoothBroadcastDialog.KEY_APP_LABEL,
Utils.getApplicationLabel(mContext, getWorker().getPackageName()));
intent.putExtra(BluetoothBroadcastDialog.KEY_DEVICE_ADDRESS,
bluetoothDevice.getAddress());
pi = PendingIntent.getActivity(context, 0 /* requestCode */, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
} }
final PendingIntent pi = PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
final IconCompat icon = getBroadcastIcon(context); final IconCompat icon = getBroadcastIcon(context);
return SliceAction.createDeeplink(pi, icon, ListBuilder.ICON_IMAGE, getPreferenceKey()); return SliceAction.createDeeplink(pi, icon, ListBuilder.ICON_IMAGE, getPreferenceKey());