1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.bluetooth; 18 19 import android.app.Dialog; 20 import android.app.settings.SettingsEnums; 21 import android.content.Context; 22 import android.content.DialogInterface; 23 import android.content.Intent; 24 import android.os.Bundle; 25 import android.text.TextUtils; 26 import android.util.Log; 27 import android.view.View; 28 import android.widget.Button; 29 import android.widget.TextView; 30 31 import androidx.annotation.NonNull; 32 import androidx.appcompat.app.AlertDialog; 33 34 import com.android.settings.R; 35 import com.android.settings.core.SubSettingLauncher; 36 import com.android.settings.core.instrumentation.InstrumentedDialogFragment; 37 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; 38 import com.android.settingslib.bluetooth.LocalBluetoothManager; 39 import com.android.settingslib.media.MediaOutputConstants; 40 41 /** 42 * This Dialog allowed users to do some actions for broadcast media or find the 43 * nearby broadcast sources. 44 */ 45 public class BluetoothBroadcastDialog extends InstrumentedDialogFragment { 46 47 public static final String KEY_APP_LABEL = "app_label"; 48 public static final String KEY_DEVICE_ADDRESS = 49 BluetoothFindBroadcastsFragment.KEY_DEVICE_ADDRESS; 50 public static final String KEY_MEDIA_STREAMING = "media_streaming"; 51 52 private static final String TAG = "BTBroadcastsDialog"; 53 private static final CharSequence UNKNOWN_APP_LABEL = "unknown"; 54 private Context mContext; 55 private CharSequence mCurrentAppLabel = UNKNOWN_APP_LABEL; 56 private String mDeviceAddress; 57 private boolean mIsMediaStreaming; 58 private LocalBluetoothManager mLocalBluetoothManager; 59 private AlertDialog mAlertDialog; 60 61 @Override onCreate(Bundle savedInstanceState)62 public void onCreate(Bundle savedInstanceState) { 63 super.onCreate(savedInstanceState); 64 mContext = getActivity(); 65 mCurrentAppLabel = getActivity().getIntent().getCharSequenceExtra(KEY_APP_LABEL); 66 mDeviceAddress = getActivity().getIntent().getStringExtra(KEY_DEVICE_ADDRESS); 67 mIsMediaStreaming = getActivity().getIntent().getBooleanExtra(KEY_MEDIA_STREAMING, false); 68 mLocalBluetoothManager = Utils.getLocalBtManager(mContext); 69 setShowsDialog(true); 70 } 71 72 @Override onCreateDialog(Bundle savedInstanceState)73 public Dialog onCreateDialog(Bundle savedInstanceState) { 74 View layout = View.inflate(mContext, 75 com.android.settingslib.R.layout.broadcast_dialog, null); 76 77 TextView title = layout.findViewById(com.android.settingslib.R.id.dialog_title); 78 TextView subTitle = layout.findViewById(com.android.settingslib.R.id.dialog_subtitle); 79 80 Button broadcastBtn = layout.findViewById(com.android.settingslib.R.id.positive_btn); 81 if (isBroadcastSupported() && mIsMediaStreaming) { 82 title.setText(mContext.getString(R.string.bluetooth_broadcast_dialog_title)); 83 subTitle.setText( 84 mContext.getString(R.string.bluetooth_broadcast_dialog_broadcast_message)); 85 broadcastBtn.setVisibility(View.VISIBLE); 86 if (TextUtils.isEmpty(mCurrentAppLabel)) { 87 broadcastBtn.setText(mContext.getString(R.string.bluetooth_broadcast_dialog_title)); 88 } else { 89 broadcastBtn.setText(mContext.getString( 90 R.string.bluetooth_broadcast_dialog_broadcast_app, 91 String.valueOf(mCurrentAppLabel))); 92 } 93 broadcastBtn.setOnClickListener((view) -> { 94 launchMediaOutputBroadcastDialog(); 95 }); 96 } else { 97 title.setText(mContext.getString(R.string.bluetooth_find_broadcast)); 98 subTitle.setText( 99 mContext.getString(R.string.bluetooth_broadcast_dialog_find_message)); 100 broadcastBtn.setVisibility(View.GONE); 101 } 102 103 Button findBroadcastBtn = layout.findViewById(com.android.settingslib.R.id.negative_btn); 104 findBroadcastBtn.setText(mContext.getString(R.string.bluetooth_find_broadcast)); 105 findBroadcastBtn.setOnClickListener((view) -> { 106 launchFindBroadcastsActivity(); 107 }); 108 109 Button cancelBtn = layout.findViewById(com.android.settingslib.R.id.neutral_btn); 110 cancelBtn.setOnClickListener((view) -> { 111 dismiss(); 112 getActivity().finish(); 113 }); 114 115 mAlertDialog = new AlertDialog.Builder(mContext, 116 com.android.settingslib.widget.theme.R.style.Theme_AlertDialog_SettingsLib) 117 .setView(layout) 118 .create(); 119 120 return mAlertDialog; 121 } 122 123 @Override onStart()124 public void onStart() { 125 super.onStart(); 126 } 127 128 @Override getMetricsCategory()129 public int getMetricsCategory() { 130 return SettingsEnums.DIALOG_LE_AUDIO_BROADCAST; 131 } 132 133 @Override onCancel(@onNull DialogInterface dialog)134 public void onCancel(@NonNull DialogInterface dialog) { 135 dismiss(); 136 getActivity().finish(); 137 } 138 launchFindBroadcastsActivity()139 private void launchFindBroadcastsActivity() { 140 Bundle bundle = new Bundle(); 141 bundle.putString(KEY_DEVICE_ADDRESS, mDeviceAddress); 142 143 new SubSettingLauncher(mContext) 144 .setTitleRes(R.string.bluetooth_find_broadcast_title) 145 .setDestination(BluetoothFindBroadcastsFragment.class.getName()) 146 .setArguments(bundle) 147 .setSourceMetricsCategory(SettingsEnums.PAGE_UNKNOWN) 148 .launch(); 149 dismissVolumePanel(); 150 } 151 launchMediaOutputBroadcastDialog()152 private void launchMediaOutputBroadcastDialog() { 153 if (startBroadcast()) { 154 mContext.sendBroadcast(new Intent() 155 .setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME) 156 .setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG) 157 .putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME, 158 getActivity().getPackageName())); 159 dismissVolumePanel(); 160 } 161 } 162 getLEAudioBroadcastProfile()163 private LocalBluetoothLeBroadcast getLEAudioBroadcastProfile() { 164 if (mLocalBluetoothManager != null && mLocalBluetoothManager.getProfileManager() != null) { 165 LocalBluetoothLeBroadcast bluetoothLeBroadcast = 166 mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile(); 167 if (bluetoothLeBroadcast != null) { 168 return bluetoothLeBroadcast; 169 } 170 } 171 Log.d(TAG, "Can not get LE Audio Broadcast Profile"); 172 return null; 173 } 174 startBroadcast()175 private boolean startBroadcast() { 176 LocalBluetoothLeBroadcast btLeBroadcast = getLEAudioBroadcastProfile(); 177 if (btLeBroadcast != null) { 178 btLeBroadcast.startBroadcast(String.valueOf(mCurrentAppLabel), null); 179 return true; 180 } 181 Log.d(TAG, "Can not broadcast successfully"); 182 return false; 183 } 184 dismissVolumePanel()185 private void dismissVolumePanel() { 186 // Dismiss volume panel 187 mContext.sendBroadcast(new Intent() 188 .setPackage(MediaOutputConstants.SETTINGS_PACKAGE_NAME) 189 .setAction(MediaOutputConstants.ACTION_CLOSE_PANEL)); 190 } 191 isBroadcastSupported()192 boolean isBroadcastSupported() { 193 LocalBluetoothLeBroadcast broadcast = 194 mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile(); 195 return broadcast != null; 196 } 197 } 198