• 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 android.bluetooth.BluetoothDevice;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.media.AudioManager;
23 import android.media.session.MediaController;
24 import android.media.session.MediaSessionManager;
25 import android.text.TextUtils;
26 
27 import androidx.preference.Preference;
28 import androidx.preference.PreferenceScreen;
29 
30 import com.android.settings.R;
31 import com.android.settings.media.MediaOutputUtils;
32 import com.android.settingslib.Utils;
33 import com.android.settingslib.bluetooth.A2dpProfile;
34 import com.android.settingslib.bluetooth.HearingAidProfile;
35 import com.android.settingslib.media.MediaOutputConstants;
36 
37 import java.util.List;
38 
39 /**
40  * This class allows launching MediaOutputDialog to switch output device.
41  * Preference would hide only when
42  * - Bluetooth = OFF
43  * - Bluetooth = ON and Connected Devices = 0 and Previously Connected = 0
44  * - Media stream captured by remote device
45  * - During a call.
46  */
47 public class MediaOutputPreferenceController extends AudioSwitchPreferenceController {
48 
49     private MediaController mMediaController;
50 
MediaOutputPreferenceController(Context context, String key)51     public MediaOutputPreferenceController(Context context, String key) {
52         super(context, key);
53         mMediaController = MediaOutputUtils.getActiveLocalMediaController(context.getSystemService(
54                 MediaSessionManager.class));
55     }
56 
57     @Override
displayPreference(PreferenceScreen screen)58     public void displayPreference(PreferenceScreen screen) {
59         super.displayPreference(screen);
60 
61         if (!Utils.isAudioModeOngoingCall(mContext) && mMediaController != null) {
62             mPreference.setVisible(true);
63         }
64     }
65 
66     @Override
updateState(Preference preference)67     public void updateState(Preference preference) {
68         if (preference == null) {
69             // In case UI is not ready.
70             return;
71         }
72 
73         if (mMediaController == null) {
74             // No active local playback
75             return;
76         }
77 
78         if (Utils.isAudioModeOngoingCall(mContext)) {
79             // Ongoing call status, switch entry for media will be disabled.
80             mPreference.setVisible(false);
81             preference.setSummary(
82                     mContext.getText(R.string.media_out_summary_ongoing_call_state));
83             return;
84         }
85 
86         BluetoothDevice activeDevice = null;
87         // Show preference if there is connected or previously connected device
88         // Find active device and set its name as the preference's summary
89         List<BluetoothDevice> connectedA2dpDevices = getConnectedA2dpDevices();
90         List<BluetoothDevice> connectedHADevices = getConnectedHearingAidDevices();
91         if (mAudioManager.getMode() == AudioManager.MODE_NORMAL
92                 && ((connectedA2dpDevices != null && !connectedA2dpDevices.isEmpty())
93                 || (connectedHADevices != null && !connectedHADevices.isEmpty()))) {
94             activeDevice = findActiveDevice();
95         }
96         mPreference.setTitle(mContext.getString(R.string.media_output_label_title,
97                 com.android.settings.Utils.getApplicationLabel(mContext,
98                         mMediaController.getPackageName())));
99         mPreference.setSummary((activeDevice == null) ?
100                 mContext.getText(R.string.media_output_default_summary) :
101                 activeDevice.getAlias());
102     }
103 
104     @Override
findActiveDevice()105     public BluetoothDevice findActiveDevice() {
106         BluetoothDevice activeDevice = findActiveHearingAidDevice();
107         final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
108 
109         if (activeDevice == null && a2dpProfile != null) {
110             activeDevice = a2dpProfile.getActiveDevice();
111         }
112         return activeDevice;
113     }
114 
115     /**
116      * Find active hearing aid device
117      */
118     @Override
findActiveHearingAidDevice()119     protected BluetoothDevice findActiveHearingAidDevice() {
120         final HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile();
121 
122         if (hearingAidProfile != null) {
123             List<BluetoothDevice> activeDevices = hearingAidProfile.getActiveDevices();
124             for (BluetoothDevice btDevice : activeDevices) {
125                 if (btDevice != null) {
126                     return btDevice;
127                 }
128             }
129         }
130         return null;
131     }
132 
133     @Override
handlePreferenceTreeClick(Preference preference)134     public boolean handlePreferenceTreeClick(Preference preference) {
135         if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
136             mContext.sendBroadcast(new Intent()
137                     .setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
138                     .setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME)
139                     .putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME,
140                             mMediaController.getPackageName())
141                     .putExtra(MediaOutputConstants.KEY_MEDIA_SESSION_TOKEN,
142                             mMediaController.getSessionToken()));
143             return true;
144         }
145         return false;
146     }
147 }
148