1 /* 2 * Copyright (C) 2024 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.content.DialogInterface; 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 import androidx.lifecycle.Lifecycle; 30 31 import com.android.settings.R; 32 import com.android.settings.core.instrumentation.InstrumentedDialogFragment; 33 import com.android.settingslib.bluetooth.BluetoothUtils; 34 35 public class AudioSharingIncompatibleDialogFragment extends InstrumentedDialogFragment { 36 private static final String TAG = "AudioSharingIncompatDlg"; 37 38 private static final String BUNDLE_KEY_DEVICE_NAME = "bundle_key_device_name"; 39 40 // The host creates an instance of this dialog fragment must implement this interface to receive 41 // event callbacks. 42 public interface DialogEventListener { 43 /** 44 * Called when the dialog is dismissed. 45 */ onDialogDismissed()46 void onDialogDismissed(); 47 } 48 49 @Nullable 50 private static DialogEventListener sListener; 51 52 @Override getMetricsCategory()53 public int getMetricsCategory() { 54 // TODO: add metrics 55 return 0; 56 } 57 58 /** 59 * Display the {@link AudioSharingIncompatibleDialogFragment} dialog. 60 * 61 * @param host The Fragment this dialog will be hosted. 62 */ show(@ullable Fragment host, @NonNull String deviceName, @NonNull DialogEventListener listener)63 public static void show(@Nullable Fragment host, @NonNull String deviceName, 64 @NonNull DialogEventListener listener) { 65 if (host == null) { 66 Log.d(TAG, "Fail to show dialog, host is null"); 67 return; 68 } 69 if (BluetoothUtils.isAudioSharingUIAvailable(host.getContext())) { 70 final FragmentManager manager; 71 try { 72 manager = host.getChildFragmentManager(); 73 } catch (IllegalStateException e) { 74 Log.d(TAG, "Fail to show dialog: " + e.getMessage()); 75 return; 76 } 77 Lifecycle.State currentState = host.getLifecycle().getCurrentState(); 78 if (!currentState.isAtLeast(Lifecycle.State.STARTED)) { 79 Log.d(TAG, "Fail to show dialog with state: " + currentState); 80 return; 81 } 82 sListener = listener; 83 AlertDialog dialog = AudioSharingDialogHelper.getDialogIfShowing(manager, TAG); 84 if (dialog != null) { 85 Log.d(TAG, "Dialog is showing, return."); 86 return; 87 } 88 Log.d(TAG, "Show up the incompatible device dialog."); 89 final Bundle bundle = new Bundle(); 90 bundle.putString(BUNDLE_KEY_DEVICE_NAME, deviceName); 91 AudioSharingIncompatibleDialogFragment dialogFrag = 92 new AudioSharingIncompatibleDialogFragment(); 93 dialogFrag.setArguments(bundle); 94 dialogFrag.show(manager, TAG); 95 } 96 } 97 98 @Override 99 @NonNull onCreateDialog(@ullable Bundle savedInstanceState)100 public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { 101 Bundle arguments = requireArguments(); 102 String deviceName = arguments.getString(BUNDLE_KEY_DEVICE_NAME); 103 AlertDialog dialog = 104 AudioSharingDialogFactory.newBuilder(getActivity()) 105 .setTitle(getString(R.string.audio_sharing_incompatible_dialog_title, 106 deviceName)) 107 .setTitleIcon(R.drawable.ic_warning_24dp) 108 .setIsCustomBodyEnabled(true) 109 .setCustomMessage(R.string.audio_sharing_incompatible_dialog_content) 110 .setPositiveButton(R.string.okay, (d, w) -> {}) 111 .build(); 112 dialog.setCanceledOnTouchOutside(true); 113 return dialog; 114 } 115 116 @Override onDismiss(@onNull DialogInterface dialog)117 public void onDismiss(@NonNull DialogInterface dialog) { 118 super.onDismiss(dialog); 119 if (sListener != null) { 120 sListener.onDialogDismissed(); 121 } 122 } 123 } 124