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.bluetooth.BluetoothAdapter; 22 import android.bluetooth.BluetoothDevice; 23 import android.content.Context; 24 import android.os.Bundle; 25 26 import androidx.annotation.NonNull; 27 import androidx.annotation.Nullable; 28 import androidx.appcompat.app.AlertDialog; 29 30 import com.android.settings.R; 31 import com.android.settings.accessibility.HearingDevicePairingFragment; 32 import com.android.settings.core.SubSettingLauncher; 33 import com.android.settings.core.instrumentation.InstrumentedDialogFragment; 34 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 35 import com.android.settingslib.bluetooth.HearingAidInfo; 36 import com.android.settingslib.bluetooth.LocalBluetoothManager; 37 38 /** 39 * Provides a dialog to pair another side of hearing aid device. 40 */ 41 public class HearingAidPairingDialogFragment extends InstrumentedDialogFragment implements 42 CachedBluetoothDevice.Callback { 43 public static final String TAG = "HearingAidPairingDialogFragment"; 44 private static final String KEY_DEVICE_ADDRESS = "device_address"; 45 private static final String KEY_LAUNCH_PAGE = "launch_page"; 46 47 private LocalBluetoothManager mLocalBluetoothManager; 48 private CachedBluetoothDevice mDevice; 49 50 /** 51 * Creates a new {@link HearingAidPairingDialogFragment} and shows pair another side of hearing 52 * aid device according to {@code deviceAddress}. 53 * 54 * @param deviceAddress The remote Bluetooth device address, that needs to be a hearing aid 55 * device. 56 * @param launchPage The id of the page where this dialog launch from. Should be one of 57 * {@link SettingsEnums#ACCESSIBILITY}, 58 * {@link SettingsEnums#ACCESSIBILITY_HEARING_AID_SETTINGS}, or 59 * {@link SettingsEnums#SETTINGS_CONNECTED_DEVICE_CATEGORY} 60 * @return a DialogFragment 61 */ newInstance(String deviceAddress, int launchPage)62 public static HearingAidPairingDialogFragment newInstance(String deviceAddress, 63 int launchPage) { 64 Bundle args = new Bundle(1); 65 args.putString(KEY_DEVICE_ADDRESS, deviceAddress); 66 args.putInt(KEY_LAUNCH_PAGE, launchPage); 67 final HearingAidPairingDialogFragment fragment = new HearingAidPairingDialogFragment(); 68 fragment.setArguments(args); 69 return fragment; 70 } 71 72 @Override onAttach(Context context)73 public void onAttach(Context context) { 74 super.onAttach(context); 75 mLocalBluetoothManager = Utils.getLocalBtManager(context); 76 mDevice = getDevice(); 77 if (mDevice != null) { 78 mDevice.registerCallback(this); 79 } 80 } 81 82 @Override onDetach()83 public void onDetach() { 84 super.onDetach(); 85 if (mDevice != null) { 86 mDevice.unregisterCallback(this); 87 } 88 } 89 getDevice()90 private CachedBluetoothDevice getDevice() { 91 final String deviceAddress = getArguments().getString(KEY_DEVICE_ADDRESS); 92 final BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice( 93 deviceAddress); 94 return mLocalBluetoothManager.getCachedDeviceManager().findDevice(device); 95 } 96 97 @Override getMetricsCategory()98 public int getMetricsCategory() { 99 return SettingsEnums.DIALOG_ACCESSIBILITY_HEARING_AID_PAIR_ANOTHER; 100 } 101 102 @NonNull 103 @Override onCreateDialog(@ullable Bundle savedInstanceState)104 public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { 105 final int deviceSide = mDevice.getDeviceSide(); 106 final int titleId = R.string.bluetooth_pair_other_ear_dialog_title; 107 final int messageId = (deviceSide == HearingAidInfo.DeviceSide.SIDE_LEFT) 108 ? R.string.bluetooth_pair_other_ear_dialog_left_ear_message 109 : R.string.bluetooth_pair_other_ear_dialog_right_ear_message; 110 final int pairBtnId = (deviceSide == HearingAidInfo.DeviceSide.SIDE_LEFT) 111 ? R.string.bluetooth_pair_other_ear_dialog_right_ear_positive_button 112 : R.string.bluetooth_pair_other_ear_dialog_left_ear_positive_button; 113 114 return new AlertDialog.Builder(getActivity()) 115 .setTitle(titleId) 116 .setMessage(messageId) 117 .setNegativeButton(android.R.string.cancel, /* listener= */ null) 118 .setPositiveButton(pairBtnId, (dialog, which) -> positiveButtonListener()) 119 .create(); 120 } 121 positiveButtonListener()122 private void positiveButtonListener() { 123 final int launchPage = getArguments().getInt(KEY_LAUNCH_PAGE); 124 final boolean launchFromA11y = (launchPage == SettingsEnums.ACCESSIBILITY) 125 || (launchPage == SettingsEnums.ACCESSIBILITY_HEARING_AID_SETTINGS); 126 final String destination = launchFromA11y 127 ? HearingDevicePairingFragment.class.getName() 128 : BluetoothPairingDetail.class.getName(); 129 new SubSettingLauncher(getActivity()) 130 .setDestination(destination) 131 .setSourceMetricsCategory(getMetricsCategory()) 132 .launch(); 133 } 134 135 @Override onDeviceAttributesChanged()136 public void onDeviceAttributesChanged() { 137 final CachedBluetoothDevice subDevice = mDevice.getSubDevice(); 138 if (subDevice != null && subDevice.isConnectedAshaHearingAidDevice()) { 139 this.dismiss(); 140 } 141 } 142 } 143