1 /* 2 * Copyright (C) 2023 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.connecteddevice.audiosharing; 18 19 import android.app.Dialog; 20 import android.app.settings.SettingsEnums; 21 import android.os.Bundle; 22 import android.util.Log; 23 24 import androidx.annotation.NonNull; 25 import androidx.annotation.Nullable; 26 import androidx.appcompat.app.AlertDialog; 27 import androidx.fragment.app.Fragment; 28 import androidx.fragment.app.FragmentManager; 29 30 import com.android.settings.R; 31 import com.android.settings.core.instrumentation.InstrumentedDialogFragment; 32 import com.android.settingslib.bluetooth.BluetoothUtils; 33 34 import java.util.List; 35 36 /** Provides a dialog to choose the active device for calls and alarms. */ 37 public class AudioSharingCallAudioDialogFragment extends InstrumentedDialogFragment { 38 private static final String TAG = "CallsAndAlarmsDialog"; 39 private static final String BUNDLE_KEY_DEVICE_ITEMS = "bundle_key_device_items"; 40 private static final String BUNDLE_KEY_CHECKED_ITEM_INDEX = "bundle_key_checked_index"; 41 42 // The host creates an instance of this dialog fragment must implement this interface to receive 43 // event callbacks. 44 public interface DialogEventListener { 45 /** 46 * Called when users click the device item to set active for calls and alarms in the dialog. 47 * 48 * @param item The device item clicked. 49 */ onItemClick(AudioSharingDeviceItem item)50 void onItemClick(AudioSharingDeviceItem item); 51 } 52 53 @Nullable private static DialogEventListener sListener; 54 55 @Override getMetricsCategory()56 public int getMetricsCategory() { 57 return SettingsEnums.DIALOG_AUDIO_SHARING_CALL_AUDIO; 58 } 59 60 /** 61 * Display the {@link AudioSharingCallAudioDialogFragment} dialog. 62 * 63 * @param host The Fragment this dialog will be hosted. 64 * @param deviceItems The connected device items in audio sharing session. 65 * @param listener The callback to handle the user action on this dialog. 66 */ show( @ullable Fragment host, @NonNull List<AudioSharingDeviceItem> deviceItems, int checkedItemIndex, @NonNull DialogEventListener listener)67 public static void show( 68 @Nullable Fragment host, 69 @NonNull List<AudioSharingDeviceItem> deviceItems, 70 int checkedItemIndex, 71 @NonNull DialogEventListener listener) { 72 if (host == null) { 73 Log.d(TAG, "Fail to show dialog, host is null"); 74 return; 75 } 76 if (BluetoothUtils.isAudioSharingUIAvailable(host.getContext())) { 77 final FragmentManager manager; 78 try { 79 manager = host.getChildFragmentManager(); 80 } catch (IllegalStateException e) { 81 Log.d(TAG, "Fail to show dialog: " + e.getMessage()); 82 return; 83 } 84 sListener = listener; 85 if (manager.findFragmentByTag(TAG) == null) { 86 final Bundle bundle = new Bundle(); 87 bundle.putParcelableList(BUNDLE_KEY_DEVICE_ITEMS, deviceItems); 88 bundle.putInt(BUNDLE_KEY_CHECKED_ITEM_INDEX, checkedItemIndex); 89 final AudioSharingCallAudioDialogFragment dialog = 90 new AudioSharingCallAudioDialogFragment(); 91 dialog.setArguments(bundle); 92 dialog.show(manager, TAG); 93 } 94 } 95 } 96 97 @Override 98 @NonNull onCreateDialog(Bundle savedInstanceState)99 public Dialog onCreateDialog(Bundle savedInstanceState) { 100 Bundle arguments = requireArguments(); 101 List<AudioSharingDeviceItem> deviceItems = 102 arguments.getParcelable(BUNDLE_KEY_DEVICE_ITEMS, List.class); 103 int checkedItemIndex = arguments.getInt(BUNDLE_KEY_CHECKED_ITEM_INDEX, -1); 104 AlertDialog.Builder builder = 105 new AlertDialog.Builder(getActivity()) 106 .setTitle(R.string.audio_sharing_call_audio_title); 107 if (deviceItems == null) { 108 Log.d(TAG, "Create dialog error: null deviceItems"); 109 return builder.create(); 110 } 111 String[] choices = 112 deviceItems.stream().map(AudioSharingDeviceItem::getName).toArray(String[]::new); 113 builder.setSingleChoiceItems( 114 choices, 115 checkedItemIndex, 116 (dialog, which) -> { 117 if (sListener != null) { 118 sListener.onItemClick(deviceItems.get(which)); 119 } 120 }); 121 return builder.create(); 122 } 123 } 124