AudioManager#getMode is a slow binder call which should not be called on UI thread. isFilterMatched will be frequently triggered on UI thread when updating the Connected devices page. Cache and update the audio mode when receive onModeChanged callback in this change. For long term, we should better separate the UI/background thread tasks in those classes. Also send request to Audio team to improve the API latency. Flag: EXEMPT small fix Bug: 380993178 Test: atest Change-Id: I054f3fa62f0fdf03b9a436a532ac1fb4738aaf58
164 lines
6.4 KiB
Java
164 lines
6.4 KiB
Java
/*
|
|
* Copyright 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package com.android.settings.bluetooth;
|
|
|
|
import android.bluetooth.BluetoothProfile;
|
|
import android.content.Context;
|
|
import android.media.AudioManager;
|
|
import android.util.Log;
|
|
|
|
import androidx.preference.Preference;
|
|
|
|
import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
|
import com.android.settingslib.bluetooth.BluetoothUtils;
|
|
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
|
import com.android.settingslib.utils.ThreadUtils;
|
|
|
|
/** Controller to maintain available media Bluetooth devices */
|
|
public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater
|
|
implements Preference.OnPreferenceClickListener {
|
|
|
|
private static final String TAG = "AvailableMediaBluetoothDeviceUpdater";
|
|
private static final boolean DBG = Log.isLoggable(BluetoothDeviceUpdater.TAG, Log.DEBUG);
|
|
|
|
private static final String PREF_KEY_PREFIX = "available_media_bt_";
|
|
|
|
private final AudioManager mAudioManager;
|
|
private final LocalBluetoothManager mLocalBtManager;
|
|
private int mAudioMode;
|
|
|
|
public AvailableMediaBluetoothDeviceUpdater(
|
|
Context context,
|
|
DevicePreferenceCallback devicePreferenceCallback,
|
|
int metricsCategory) {
|
|
super(context, devicePreferenceCallback, metricsCategory);
|
|
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
|
mLocalBtManager = Utils.getLocalBtManager(context);
|
|
mAudioMode = mAudioManager.getMode();
|
|
}
|
|
|
|
@Override
|
|
public void onAudioModeChanged() {
|
|
// TODO: move to background thread
|
|
mAudioMode = mAudioManager.getMode();
|
|
forceUpdate();
|
|
}
|
|
|
|
@Override
|
|
public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
|
|
final int currentAudioProfile;
|
|
|
|
if (mAudioMode == AudioManager.MODE_RINGTONE
|
|
|| mAudioMode == AudioManager.MODE_IN_CALL
|
|
|| mAudioMode == AudioManager.MODE_IN_COMMUNICATION) {
|
|
// in phone call
|
|
currentAudioProfile = BluetoothProfile.HEADSET;
|
|
} else {
|
|
// without phone call
|
|
currentAudioProfile = BluetoothProfile.A2DP;
|
|
}
|
|
|
|
boolean isFilterMatched = false;
|
|
if (isDeviceConnected(cachedDevice) && isDeviceInCachedDevicesList(cachedDevice)) {
|
|
Log.d(TAG, "isFilterMatched() current audio profile : " + currentAudioProfile);
|
|
|
|
// If device is LE Audio, it is compatible with HFP and A2DP.
|
|
// It would show in Available Devices group if the audio sharing flag is disabled or
|
|
// the device is not in the audio sharing session.
|
|
if (cachedDevice.isConnectedLeAudioDevice()) {
|
|
if (BluetoothUtils.isAudioSharingUIAvailable(mContext)
|
|
&& BluetoothUtils.hasConnectedBroadcastSource(
|
|
cachedDevice, mLocalBtManager)) {
|
|
Log.d(
|
|
TAG,
|
|
"Filter out device : "
|
|
+ cachedDevice.getName()
|
|
+ ", it is in audio sharing.");
|
|
return false;
|
|
|
|
} else {
|
|
Log.d(
|
|
TAG,
|
|
"isFilterMatched() device : "
|
|
+ cachedDevice.getName()
|
|
+ ", the LE Audio profile is connected and not in sharing "
|
|
+ "if broadcast enabled.");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// If device is Hearing Aid, it is compatible with HFP and A2DP.
|
|
// It would show in Available Devices group.
|
|
if (cachedDevice.isConnectedAshaHearingAidDevice()) {
|
|
Log.d(
|
|
TAG,
|
|
"isFilterMatched() device : "
|
|
+ cachedDevice.getName()
|
|
+ ", the Hearing Aid profile is connected.");
|
|
return true;
|
|
}
|
|
|
|
// According to the current audio profile type,
|
|
// this page will show the bluetooth device that have corresponding profile.
|
|
// For example:
|
|
// If current audio profile is a2dp, show the bluetooth device that have a2dp profile.
|
|
// If current audio profile is headset,
|
|
// show the bluetooth device that have headset profile.
|
|
switch (currentAudioProfile) {
|
|
case BluetoothProfile.A2DP:
|
|
isFilterMatched = cachedDevice.isConnectedA2dpDevice();
|
|
break;
|
|
case BluetoothProfile.HEADSET:
|
|
isFilterMatched = cachedDevice.isConnectedHfpDevice();
|
|
break;
|
|
}
|
|
Log.d(
|
|
TAG,
|
|
"isFilterMatched() device : "
|
|
+ cachedDevice.getName()
|
|
+ ", isFilterMatched : "
|
|
+ isFilterMatched);
|
|
}
|
|
return isFilterMatched;
|
|
}
|
|
|
|
@Override
|
|
public boolean onPreferenceClick(Preference preference) {
|
|
mMetricsFeatureProvider.logClickedPreference(preference, mMetricsCategory);
|
|
var unused =
|
|
ThreadUtils.postOnBackgroundThread(
|
|
() -> mDevicePreferenceCallback.onDeviceClick(preference));
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
protected String getPreferenceKeyPrefix() {
|
|
return PREF_KEY_PREFIX;
|
|
}
|
|
|
|
@Override
|
|
protected String getLogTag() {
|
|
return TAG;
|
|
}
|
|
|
|
@Override
|
|
protected void update(CachedBluetoothDevice cachedBluetoothDevice) {
|
|
super.update(cachedBluetoothDevice);
|
|
Log.d(TAG, "Map : " + mPreferenceMap);
|
|
}
|
|
}
|