blob: 4ec00e358a950e20b76189570d7933fa057ec09c [file] [log] [blame]
ryanywlin63bdfa82018-03-23 16:57:51 +08001/*
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
17package com.android.settings.sound;
18
ryanywlin63bdfa82018-03-23 16:57:51 +080019import android.bluetooth.BluetoothDevice;
20import android.content.Context;
timhypengabdf7392019-03-04 16:32:47 +080021import android.content.Intent;
ryanywlin63bdfa82018-03-23 16:57:51 +080022import android.media.AudioManager;
Tim Pengf392eae2020-05-06 13:52:24 +080023import android.media.session.MediaController;
24import android.media.session.MediaSessionManager;
timhypengabdf7392019-03-04 16:32:47 +080025import android.text.TextUtils;
ryanywlin63bdfa82018-03-23 16:57:51 +080026
Fan Zhang23f8d592018-08-28 15:11:40 -070027import androidx.preference.Preference;
Tim Peng9d3092c2020-03-27 20:24:06 +080028import androidx.preference.PreferenceScreen;
Fan Zhang23f8d592018-08-28 15:11:40 -070029
ryanywlin63bdfa82018-03-23 16:57:51 +080030import com.android.settings.R;
Hugh Chene16a8072020-10-07 15:55:51 +080031import com.android.settings.media.MediaOutputUtils;
Fan Zhangc7162cd2018-06-18 15:21:41 -070032import com.android.settingslib.Utils;
ryanywlin63bdfa82018-03-23 16:57:51 +080033import com.android.settingslib.bluetooth.A2dpProfile;
ryanywlin8276d962018-04-28 07:26:46 +080034import com.android.settingslib.bluetooth.HearingAidProfile;
timhypenga7a73c42020-12-22 21:15:49 +080035import com.android.settingslib.media.MediaOutputConstants;
timhypengabdf7392019-03-04 16:32:47 +080036
37import java.util.List;
ryanywlin63bdfa82018-03-23 16:57:51 +080038
39/**
timhypengdeb93062020-12-15 14:25:22 +080040 * This class allows launching MediaOutputDialog to switch output device.
timhypengabdf7392019-03-04 16:32:47 +080041 * 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
ryanywlin63bdfa82018-03-23 16:57:51 +080045 * - During a call.
46 */
timhypengeee759e2020-10-06 12:12:53 +080047public class MediaOutputPreferenceController extends AudioSwitchPreferenceController {
ryanywlin63bdfa82018-03-23 16:57:51 +080048
Tim Pengf392eae2020-05-06 13:52:24 +080049 private MediaController mMediaController;
50
ryanywlin63bdfa82018-03-23 16:57:51 +080051 public MediaOutputPreferenceController(Context context, String key) {
52 super(context, key);
Hugh Chene16a8072020-10-07 15:55:51 +080053 mMediaController = MediaOutputUtils.getActiveLocalMediaController(context.getSystemService(
54 MediaSessionManager.class));
ryanywlin63bdfa82018-03-23 16:57:51 +080055 }
56
57 @Override
Tim Peng9d3092c2020-03-27 20:24:06 +080058 public void displayPreference(PreferenceScreen screen) {
59 super.displayPreference(screen);
60
Tim Pengf392eae2020-05-06 13:52:24 +080061 if (!Utils.isAudioModeOngoingCall(mContext) && mMediaController != null) {
Tim Peng9d3092c2020-03-27 20:24:06 +080062 mPreference.setVisible(true);
63 }
64 }
65
66 @Override
ryanywlin63bdfa82018-03-23 16:57:51 +080067 public void updateState(Preference preference) {
68 if (preference == null) {
69 // In case UI is not ready.
70 return;
71 }
72
Tim Pengf392eae2020-05-06 13:52:24 +080073 if (mMediaController == null) {
74 // No active local playback
75 return;
76 }
77
hughchenf4310882018-04-17 16:36:58 +080078 if (Utils.isAudioModeOngoingCall(mContext)) {
ryanywlin63bdfa82018-03-23 16:57:51 +080079 // Ongoing call status, switch entry for media will be disabled.
caxtonchan458fb232018-04-23 15:04:21 +080080 mPreference.setVisible(false);
ryanywlin63bdfa82018-03-23 16:57:51 +080081 preference.setSummary(
82 mContext.getText(R.string.media_out_summary_ongoing_call_state));
83 return;
84 }
85
timhypengabdf7392019-03-04 16:32:47 +080086 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
Tim Peng7b0f8872019-04-24 10:47:31 +080089 List<BluetoothDevice> connectedA2dpDevices = getConnectedA2dpDevices();
90 List<BluetoothDevice> connectedHADevices = getConnectedHearingAidDevices();
timhypengabdf7392019-03-04 16:32:47 +080091 if (mAudioManager.getMode() == AudioManager.MODE_NORMAL
Tim Peng7b0f8872019-04-24 10:47:31 +080092 && ((connectedA2dpDevices != null && !connectedA2dpDevices.isEmpty())
93 || (connectedHADevices != null && !connectedHADevices.isEmpty()))) {
timhypengabdf7392019-03-04 16:32:47 +080094 activeDevice = findActiveDevice();
ryanywlin63bdfa82018-03-23 16:57:51 +080095 }
Tim Pengf392eae2020-05-06 13:52:24 +080096 mPreference.setTitle(mContext.getString(R.string.media_output_label_title,
97 com.android.settings.Utils.getApplicationLabel(mContext,
98 mMediaController.getPackageName())));
timhypengabdf7392019-03-04 16:32:47 +080099 mPreference.setSummary((activeDevice == null) ?
100 mContext.getText(R.string.media_output_default_summary) :
Rahul Sabnisc96469f2019-10-22 15:34:40 -0700101 activeDevice.getAlias());
ryanywlin63bdfa82018-03-23 16:57:51 +0800102 }
hughchen244c7582018-07-05 14:59:57 +0800103
104 @Override
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 }
timhypengabdf7392019-03-04 16:32:47 +0800114
115 /**
116 * Find active hearing aid device
117 */
118 @Override
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
134 public boolean handlePreferenceTreeClick(Preference preference) {
135 if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
timhypeng3084d062020-09-26 15:43:11 +0800136 mContext.sendBroadcast(new Intent()
timhypenga7a73c42020-12-22 21:15:49 +0800137 .setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
138 .setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME)
139 .putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME,
timhypeng3084d062020-09-26 15:43:11 +0800140 mMediaController.getPackageName())
timhypenga7a73c42020-12-22 21:15:49 +0800141 .putExtra(MediaOutputConstants.KEY_MEDIA_SESSION_TOKEN,
timhypeng3084d062020-09-26 15:43:11 +0800142 mMediaController.getSessionToken()));
timhypengabdf7392019-03-04 16:32:47 +0800143 return true;
144 }
145 return false;
146 }
ryanywlin63bdfa82018-03-23 16:57:51 +0800147}