• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.connecteddevice.audiosharing;
18 
19 import android.app.settings.SettingsEnums;
20 import android.bluetooth.BluetoothCsipSetCoordinator;
21 import android.bluetooth.BluetoothDevice;
22 import android.content.Context;
23 import android.media.AudioManager;
24 import android.util.Log;
25 import android.widget.SeekBar;
26 
27 import androidx.annotation.Nullable;
28 import androidx.preference.Preference;
29 
30 import com.android.settings.bluetooth.BluetoothDevicePreference;
31 import com.android.settings.bluetooth.BluetoothDeviceUpdater;
32 import com.android.settings.bluetooth.Utils;
33 import com.android.settings.connecteddevice.DevicePreferenceCallback;
34 import com.android.settingslib.bluetooth.BluetoothUtils;
35 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
36 import com.android.settingslib.bluetooth.LocalBluetoothManager;
37 import com.android.settingslib.bluetooth.VolumeControlProfile;
38 
39 public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdater
40         implements Preference.OnPreferenceClickListener {
41 
42     private static final String TAG = "AudioSharingDeviceVolumeControlUpdater";
43 
44     private static final String PREF_KEY = "audio_sharing_volume_control";
45 
46     @Nullable private final LocalBluetoothManager mBtManager;
47     @Nullable private final VolumeControlProfile mVolumeControl;
48 
AudioSharingDeviceVolumeControlUpdater( Context context, DevicePreferenceCallback devicePreferenceCallback, int metricsCategory)49     public AudioSharingDeviceVolumeControlUpdater(
50             Context context,
51             DevicePreferenceCallback devicePreferenceCallback,
52             int metricsCategory) {
53         super(context, devicePreferenceCallback, metricsCategory);
54         mBtManager = Utils.getLocalBluetoothManager(context);
55         mVolumeControl =
56                 mBtManager == null
57                         ? null
58                         : mBtManager.getProfileManager().getVolumeControlProfile();
59     }
60 
61     @Override
isFilterMatched(CachedBluetoothDevice cachedDevice)62     public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
63         boolean isFilterMatched = false;
64         if (isDeviceConnected(cachedDevice) && isDeviceInCachedDevicesList(cachedDevice)) {
65             // If device is LE audio device and in a sharing session on current sharing device,
66             // it would show in volume control group.
67             if (cachedDevice.isConnectedLeAudioDevice()
68                     && AudioSharingUtils.isBroadcasting(mBtManager)
69                     && BluetoothUtils.hasConnectedBroadcastSource(cachedDevice, mBtManager)) {
70                 isFilterMatched = true;
71             }
72         }
73         Log.d(
74                 TAG,
75                 "isFilterMatched() device : "
76                         + cachedDevice.getName()
77                         + ", isFilterMatched : "
78                         + isFilterMatched);
79         return isFilterMatched;
80     }
81 
82     @Override
onPreferenceClick(Preference preference)83     public boolean onPreferenceClick(Preference preference) {
84         return true;
85     }
86 
87     @Override
addPreference(CachedBluetoothDevice cachedDevice)88     protected void addPreference(CachedBluetoothDevice cachedDevice) {
89         if (cachedDevice == null) return;
90         final BluetoothDevice device = cachedDevice.getDevice();
91         if (!mPreferenceMap.containsKey(device)) {
92             SeekBar.OnSeekBarChangeListener listener =
93                     new SeekBar.OnSeekBarChangeListener() {
94                         @Override
95                         public void onProgressChanged(
96                                 SeekBar seekBar, int progress, boolean fromUser) {}
97 
98                         @Override
99                         public void onStartTrackingTouch(SeekBar seekBar) {}
100 
101                         @Override
102                         public void onStopTrackingTouch(SeekBar seekBar) {
103                             int progress = seekBar.getProgress();
104                             int groupId = AudioSharingUtils.getGroupId(cachedDevice);
105                             if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
106                                     && groupId
107                                             == AudioSharingUtils.getFallbackActiveGroupId(
108                                                     mContext)) {
109                                 // Set media stream volume for primary buds, audio manager will
110                                 // update all buds volume in the audio sharing.
111                                 setAudioManagerStreamVolume(progress);
112                             } else {
113                                 // Set buds volume for other buds.
114                                 setDeviceVolume(cachedDevice, progress);
115                             }
116                         }
117                     };
118             AudioSharingDeviceVolumePreference vPreference =
119                     new AudioSharingDeviceVolumePreference(mPrefContext, cachedDevice);
120             vPreference.initialize();
121             vPreference.setOnSeekBarChangeListener(listener);
122             vPreference.setKey(getPreferenceKey());
123             vPreference.setIcon(com.android.settingslib.R.drawable.ic_bt_untethered_earbuds);
124             vPreference.setTitle(cachedDevice.getName());
125             mPreferenceMap.put(device, vPreference);
126             mDevicePreferenceCallback.onDeviceAdded(vPreference);
127         }
128     }
129 
130     @Override
getPreferenceKey()131     protected String getPreferenceKey() {
132         return PREF_KEY;
133     }
134 
135     @Override
getLogTag()136     protected String getLogTag() {
137         return TAG;
138     }
139 
140     @Override
update(CachedBluetoothDevice cachedBluetoothDevice)141     protected void update(CachedBluetoothDevice cachedBluetoothDevice) {
142         super.update(cachedBluetoothDevice);
143         Log.d(TAG, "Map : " + mPreferenceMap);
144     }
145 
146     @Override
addPreference( CachedBluetoothDevice cachedDevice, @BluetoothDevicePreference.SortType int type)147     protected void addPreference(
148             CachedBluetoothDevice cachedDevice, @BluetoothDevicePreference.SortType int type) {}
149 
150     @Override
launchDeviceDetails(Preference preference)151     protected void launchDeviceDetails(Preference preference) {}
152 
153     @Override
refreshPreference()154     public void refreshPreference() {}
155 
setDeviceVolume(CachedBluetoothDevice cachedDevice, int progress)156     private void setDeviceVolume(CachedBluetoothDevice cachedDevice, int progress) {
157         if (mVolumeControl != null) {
158             mVolumeControl.setDeviceVolume(
159                     cachedDevice.getDevice(), progress, /* isGroupOp= */ true);
160             mMetricsFeatureProvider.action(
161                     mContext,
162                     SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
163                     /* isPrimary= */ false);
164         }
165     }
166 
setAudioManagerStreamVolume(int progress)167     private void setAudioManagerStreamVolume(int progress) {
168         int seekbarRange =
169                 AudioSharingDeviceVolumePreference.MAX_VOLUME
170                         - AudioSharingDeviceVolumePreference.MIN_VOLUME;
171         try {
172             AudioManager audioManager = mContext.getSystemService(AudioManager.class);
173             int streamVolumeRange =
174                     audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
175                             - audioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC);
176             int volume = Math.round((float) progress * streamVolumeRange / seekbarRange);
177             audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
178             mMetricsFeatureProvider.action(
179                     mContext,
180                     SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
181                     /* isPrimary= */ true);
182         } catch (RuntimeException e) {
183             Log.e(TAG, "Fail to setAudioManagerStreamVolumeForFallbackDevice, error = " + e);
184         }
185     }
186 }
187