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.audiostreams; 18 19 import android.bluetooth.BluetoothAdapter; 20 import android.bluetooth.BluetoothProfile; 21 import android.content.Context; 22 import android.text.TextUtils; 23 24 import androidx.annotation.NonNull; 25 import androidx.annotation.Nullable; 26 27 import com.android.settings.R; 28 import com.android.settings.bluetooth.Utils; 29 import com.android.settingslib.bluetooth.BluetoothCallback; 30 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 31 import com.android.settingslib.bluetooth.LocalBluetoothManager; 32 import com.android.settingslib.utils.ThreadUtils; 33 34 public class AudioStreamsActiveDeviceSummaryUpdater implements BluetoothCallback { 35 private final LocalBluetoothManager mBluetoothManager; 36 private Context mContext; 37 @Nullable private String mSummary; 38 private OnSummaryChangeListener mListener; 39 AudioStreamsActiveDeviceSummaryUpdater( Context context, OnSummaryChangeListener listener)40 public AudioStreamsActiveDeviceSummaryUpdater( 41 Context context, OnSummaryChangeListener listener) { 42 mContext = context; 43 mBluetoothManager = Utils.getLocalBluetoothManager(context); 44 mListener = listener; 45 } 46 47 @Override onBluetoothStateChanged(@dapterState int bluetoothState)48 public void onBluetoothStateChanged(@AdapterState int bluetoothState) { 49 if (bluetoothState == BluetoothAdapter.STATE_OFF) { 50 notifyChangeIfNeeded(); 51 } 52 } 53 54 @Override onProfileConnectionStateChanged( @onNull CachedBluetoothDevice cachedDevice, @ConnectionState int state, int bluetoothProfile)55 public void onProfileConnectionStateChanged( 56 @NonNull CachedBluetoothDevice cachedDevice, 57 @ConnectionState int state, 58 int bluetoothProfile) { 59 if (bluetoothProfile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT 60 && (state == BluetoothAdapter.STATE_CONNECTED 61 || state == BluetoothAdapter.STATE_DISCONNECTED)) { 62 notifyChangeIfNeeded(); 63 } 64 } 65 register(boolean register)66 void register(boolean register) { 67 if (register) { 68 notifyChangeIfNeeded(); 69 mBluetoothManager.getEventManager().registerCallback(this); 70 } else { 71 mBluetoothManager.getEventManager().unregisterCallback(this); 72 } 73 } 74 notifyChangeIfNeeded()75 private void notifyChangeIfNeeded() { 76 var unused = 77 ThreadUtils.postOnBackgroundThread( 78 () -> { 79 String summary = getSummary(); 80 if (!TextUtils.equals(mSummary, summary)) { 81 mSummary = summary; 82 ThreadUtils.postOnMainThread( 83 () -> mListener.onSummaryChanged(summary)); 84 } 85 }); 86 } 87 getSummary()88 private String getSummary() { 89 var connectedSink = 90 AudioStreamsHelper.getCachedBluetoothDeviceInSharingOrLeConnected( 91 mBluetoothManager); 92 if (connectedSink.isEmpty()) { 93 return mContext.getString(R.string.audio_streams_dialog_no_le_device_title); 94 } 95 return connectedSink.get().getName(); 96 } 97 98 /** Interface definition for a callback to be invoked when the summary has been changed. */ 99 interface OnSummaryChangeListener { 100 /** 101 * Called when summary has changed. 102 * 103 * @param summary The new summary. 104 */ onSummaryChanged(String summary)105 void onSummaryChanged(String summary); 106 } 107 } 108