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.BluetoothProfile; 20 import android.content.Context; 21 import android.util.Log; 22 23 import androidx.annotation.NonNull; 24 import androidx.annotation.Nullable; 25 import androidx.annotation.VisibleForTesting; 26 import androidx.lifecycle.DefaultLifecycleObserver; 27 import androidx.lifecycle.LifecycleOwner; 28 import androidx.preference.Preference; 29 import androidx.preference.PreferenceScreen; 30 31 import com.android.settings.R; 32 import com.android.settings.bluetooth.Utils; 33 import com.android.settings.core.BasePreferenceController; 34 import com.android.settings.core.SubSettingLauncher; 35 import com.android.settingslib.bluetooth.BluetoothCallback; 36 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 37 import com.android.settingslib.bluetooth.LocalBluetoothManager; 38 import com.android.settingslib.utils.ThreadUtils; 39 40 public class AudioStreamsScanQrCodeController extends BasePreferenceController 41 implements DefaultLifecycleObserver { 42 static final int REQUEST_SCAN_BT_BROADCAST_QR_CODE = 0; 43 private static final String TAG = "AudioStreamsProgressCategoryController"; 44 @VisibleForTesting static final String KEY = "audio_streams_scan_qr_code"; 45 46 @VisibleForTesting 47 final BluetoothCallback mBluetoothCallback = 48 new BluetoothCallback() { 49 @Override 50 public void onActiveDeviceChanged( 51 @Nullable CachedBluetoothDevice activeDevice, int bluetoothProfile) { 52 if (bluetoothProfile == BluetoothProfile.LE_AUDIO) { 53 updateVisibility(); 54 } 55 } 56 }; 57 58 @Nullable private final LocalBluetoothManager mLocalBtManager; 59 @Nullable private AudioStreamsDashboardFragment mFragment; 60 @Nullable private Preference mPreference; 61 AudioStreamsScanQrCodeController(Context context, String preferenceKey)62 public AudioStreamsScanQrCodeController(Context context, String preferenceKey) { 63 super(context, preferenceKey); 64 mLocalBtManager = Utils.getLocalBtManager(mContext); 65 } 66 setFragment(AudioStreamsDashboardFragment fragment)67 public void setFragment(AudioStreamsDashboardFragment fragment) { 68 mFragment = fragment; 69 } 70 71 @Override onStart(@onNull LifecycleOwner owner)72 public void onStart(@NonNull LifecycleOwner owner) { 73 if (mLocalBtManager != null) { 74 mLocalBtManager.getEventManager().registerCallback(mBluetoothCallback); 75 } 76 } 77 78 @Override onStop(@onNull LifecycleOwner owner)79 public void onStop(@NonNull LifecycleOwner owner) { 80 if (mLocalBtManager != null) { 81 mLocalBtManager.getEventManager().unregisterCallback(mBluetoothCallback); 82 } 83 } 84 85 @Override getAvailabilityStatus()86 public int getAvailabilityStatus() { 87 return AVAILABLE; 88 } 89 90 @Override getPreferenceKey()91 public String getPreferenceKey() { 92 return KEY; 93 } 94 95 @Override displayPreference(PreferenceScreen screen)96 public void displayPreference(PreferenceScreen screen) { 97 super.displayPreference(screen); 98 mPreference = screen.findPreference(getPreferenceKey()); 99 if (mPreference == null) { 100 Log.w(TAG, "displayPreference() mPreference is null!"); 101 return; 102 } 103 mPreference.setOnPreferenceClickListener( 104 preference -> { 105 if (mFragment == null) { 106 Log.w(TAG, "displayPreference() mFragment is null!"); 107 return false; 108 } 109 if (preference.getKey().equals(KEY)) { 110 new SubSettingLauncher(mContext) 111 .setTitleRes(R.string.audio_streams_main_page_scan_qr_code_title) 112 .setDestination(AudioStreamsQrCodeScanFragment.class.getName()) 113 .setResultListener(mFragment, REQUEST_SCAN_BT_BROADCAST_QR_CODE) 114 .setSourceMetricsCategory(mFragment.getMetricsCategory()) 115 .launch(); 116 return true; 117 } 118 return false; 119 }); 120 } 121 updateVisibility()122 private void updateVisibility() { 123 var unused = 124 ThreadUtils.postOnBackgroundThread( 125 () -> { 126 boolean hasConnectedLe = 127 AudioStreamsHelper 128 .getCachedBluetoothDeviceInSharingOrLeConnected( 129 mLocalBtManager) 130 .isPresent(); 131 ThreadUtils.postOnMainThread( 132 () -> { 133 if (mPreference != null) { 134 mPreference.setVisible(hasConnectedLe); 135 } 136 }); 137 }); 138 } 139 } 140