• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_MUSIC;
21 import static android.media.AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
22 import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET;
23 
24 import com.android.settingslib.Utils;
25 
26 import android.bluetooth.BluetoothDevice;
27 import android.content.Context;
28 import android.media.AudioManager;
29 import android.support.v7.preference.Preference;
30 
31 import com.android.settings.R;
32 import com.android.settingslib.bluetooth.A2dpProfile;
33 import com.android.settingslib.bluetooth.HearingAidProfile;
34 
35 /**
36  * This class which allows switching between A2dp-connected & HAP-connected BT devices.
37  * A few conditions will disable this switcher:
38  * - No available BT device(s)
39  * - Media stream captured by cast device
40  * - During a call.
41  */
42 public class MediaOutputPreferenceController extends AudioSwitchPreferenceController {
43 
MediaOutputPreferenceController(Context context, String key)44     public MediaOutputPreferenceController(Context context, String key) {
45         super(context, key);
46     }
47 
48     @Override
updateState(Preference preference)49     public void updateState(Preference preference) {
50         if (preference == null) {
51             // In case UI is not ready.
52             return;
53         }
54 
55         if (isStreamFromOutputDevice(STREAM_MUSIC, DEVICE_OUT_REMOTE_SUBMIX)) {
56             // In cast mode, disable switch entry.
57             mPreference.setVisible(false);
58             preference.setSummary(mContext.getText(R.string.media_output_summary_unavailable));
59             return;
60         }
61 
62         if (Utils.isAudioModeOngoingCall(mContext)) {
63             // Ongoing call status, switch entry for media will be disabled.
64             mPreference.setVisible(false);
65             preference.setSummary(
66                     mContext.getText(R.string.media_out_summary_ongoing_call_state));
67             return;
68         }
69 
70         mConnectedDevices.clear();
71         // Otherwise, list all of the A2DP connected device and display the active device.
72         if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) {
73             mConnectedDevices.addAll(getConnectedA2dpDevices());
74             mConnectedDevices.addAll(getConnectedHearingAidDevices());
75         }
76 
77         final int numDevices = mConnectedDevices.size();
78         if (numDevices == 0) {
79             // Disable switch entry if there is no connected devices.
80             mPreference.setVisible(false);
81             final CharSequence summary = mContext.getText(R.string.media_output_default_summary);
82             final CharSequence[] defaultMediaOutput = new CharSequence[]{summary};
83             mSelectedIndex = getDefaultDeviceIndex();
84             preference.setSummary(summary);
85             setPreference(defaultMediaOutput, defaultMediaOutput, preference);
86             return;
87         }
88 
89         mPreference.setVisible(true);
90         CharSequence[] mediaOutputs = new CharSequence[numDevices + 1];
91         CharSequence[] mediaValues = new CharSequence[numDevices + 1];
92 
93         // Setup devices entries, select active connected device
94         setupPreferenceEntries(mediaOutputs, mediaValues, findActiveDevice(STREAM_MUSIC));
95 
96         if (isStreamFromOutputDevice(STREAM_MUSIC, DEVICE_OUT_USB_HEADSET)) {
97             // If wired headset is plugged in and active, select to default device.
98             mSelectedIndex = getDefaultDeviceIndex();
99         }
100 
101         // Display connected devices, default device and show the active device
102         setPreference(mediaOutputs, mediaValues, preference);
103     }
104 
105     @Override
setActiveBluetoothDevice(BluetoothDevice device)106     public void setActiveBluetoothDevice(BluetoothDevice device) {
107         if (mAudioManager.getMode() != AudioManager.MODE_NORMAL) {
108             return;
109         }
110         final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
111         final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
112         if (hapProfile != null && a2dpProfile != null && device == null) {
113             hapProfile.setActiveDevice(null);
114             a2dpProfile.setActiveDevice(null);
115             return;
116         }
117         if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) {
118             hapProfile.setActiveDevice(device);
119         }
120         if (a2dpProfile != null) {
121             a2dpProfile.setActiveDevice(device);
122         }
123     }
124 }
125