1 /* 2 * Copyright (C) 2018 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.sound; 18 19 import static android.bluetooth.IBluetoothHearingAid.HI_SYNC_ID_INVALID; 20 import static android.media.AudioManager.STREAM_VOICE_CALL; 21 import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET; 22 23 import com.android.settingslib.Utils; 24 25 import android.bluetooth.BluetoothDevice; 26 import android.content.Context; 27 import android.support.v7.preference.Preference; 28 29 import com.android.settings.R; 30 import com.android.settingslib.bluetooth.HeadsetProfile; 31 import com.android.settingslib.bluetooth.HearingAidProfile; 32 33 /** 34 * This class allows switching between HFP-connected & HAP-connected BT devices 35 * while in on-call state. 36 */ 37 public class HandsFreeProfileOutputPreferenceController extends 38 AudioSwitchPreferenceController { 39 40 public HandsFreeProfileOutputPreferenceController(Context context, String key) { 41 super(context, key); 42 } 43 44 @Override 45 public void updateState(Preference preference) { 46 if (preference == null) { 47 // In case UI is not ready. 48 return; 49 } 50 51 if (!Utils.isAudioModeOngoingCall(mContext)) { 52 // Without phone call, disable the switch entry. 53 mPreference.setVisible(false); 54 preference.setSummary(mContext.getText(R.string.media_output_default_summary)); 55 return; 56 } 57 58 // Ongoing call status, list all the connected devices support hands free profile. 59 // Select current active device. 60 // Disable switch entry if there is no connected device. 61 mConnectedDevices.clear(); 62 mConnectedDevices.addAll(getConnectedHfpDevices()); 63 mConnectedDevices.addAll(getConnectedHearingAidDevices()); 64 65 final int numDevices = mConnectedDevices.size(); 66 if (numDevices == 0) { 67 // No connected devices, disable switch entry. 68 mPreference.setVisible(false); 69 final CharSequence summary = mContext.getText(R.string.media_output_default_summary); 70 final CharSequence[] defaultMediaOutput = new CharSequence[]{summary}; 71 mSelectedIndex = getDefaultDeviceIndex(); 72 preference.setSummary(summary); 73 setPreference(defaultMediaOutput, defaultMediaOutput, preference); 74 return; 75 } 76 77 mPreference.setVisible(true); 78 CharSequence[] mediaOutputs = new CharSequence[numDevices + 1]; 79 CharSequence[] mediaValues = new CharSequence[numDevices + 1]; 80 81 // Setup devices entries, select active connected device 82 setupPreferenceEntries(mediaOutputs, mediaValues, findActiveDevice(STREAM_VOICE_CALL)); 83 84 if (isStreamFromOutputDevice(STREAM_VOICE_CALL, DEVICE_OUT_USB_HEADSET)) { 85 // If wired headset is plugged in and active, select to default device. 86 mSelectedIndex = getDefaultDeviceIndex(); 87 } 88 89 // Display connected devices, default device and show the active device 90 setPreference(mediaOutputs, mediaValues, preference); 91 } 92 93 @Override 94 public void setActiveBluetoothDevice(BluetoothDevice device) { 95 if (!Utils.isAudioModeOngoingCall(mContext)) { 96 return; 97 } 98 final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile(); 99 final HeadsetProfile hfpProfile = mProfileManager.getHeadsetProfile(); 100 if (hapProfile != null && hfpProfile != null && device == null) { 101 hfpProfile.setActiveDevice(null); 102 hapProfile.setActiveDevice(null); 103 return; 104 } 105 if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) { 106 hapProfile.setActiveDevice(device); 107 } 108 if (hfpProfile != null) { 109 hfpProfile.setActiveDevice(device); 110 } 111 } 112 } 113