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.bluetooth.BluetoothAdapter;
20 import android.content.Context;
21 import android.util.Log;
22 
23 import androidx.annotation.NonNull;
24 import androidx.annotation.Nullable;
25 import androidx.lifecycle.DefaultLifecycleObserver;
26 import androidx.lifecycle.LifecycleOwner;
27 import androidx.preference.Preference;
28 import androidx.preference.PreferenceScreen;
29 
30 import com.android.settings.bluetooth.Utils;
31 import com.android.settings.core.BasePreferenceController;
32 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
33 import com.android.settingslib.bluetooth.LocalBluetoothManager;
34 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
35 import com.android.settingslib.utils.ThreadUtils;
36 
37 public abstract class AudioSharingBasePreferenceController extends BasePreferenceController
38         implements DefaultLifecycleObserver {
39     private static final String TAG = "AudioSharingBasePreferenceController";
40 
41     private final BluetoothAdapter mBluetoothAdapter;
42     @Nullable private final LocalBluetoothManager mBtManager;
43     @Nullable private final LocalBluetoothProfileManager mProfileManager;
44     @Nullable protected final LocalBluetoothLeBroadcast mBroadcast;
45     @Nullable protected Preference mPreference;
46 
AudioSharingBasePreferenceController(Context context, String preferenceKey)47     public AudioSharingBasePreferenceController(Context context, String preferenceKey) {
48         super(context, preferenceKey);
49         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
50         mBtManager = Utils.getLocalBtManager(context);
51         mProfileManager = mBtManager == null ? null : mBtManager.getProfileManager();
52         mBroadcast = mProfileManager == null ? null : mProfileManager.getLeAudioBroadcastProfile();
53     }
54 
55     @Override
getAvailabilityStatus()56     public int getAvailabilityStatus() {
57         return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
58     }
59 
60     @Override
displayPreference(PreferenceScreen screen)61     public void displayPreference(PreferenceScreen screen) {
62         super.displayPreference(screen);
63         mPreference = screen.findPreference(getPreferenceKey());
64     }
65 
66     @Override
onStart(@onNull LifecycleOwner owner)67     public void onStart(@NonNull LifecycleOwner owner) {
68         updateVisibility();
69     }
70 
71     /** Update the visibility of the preference. */
updateVisibility()72     protected void updateVisibility() {
73         if (mPreference == null) {
74             Log.d(TAG, "Skip updateVisibility, null preference");
75             return;
76         }
77         var unused =
78                 ThreadUtils.postOnBackgroundThread(
79                         () -> {
80                             if (!isAvailable()) {
81                                 Log.w(TAG, "Skip updateVisibility, unavailable preference");
82                                 AudioSharingUtils.postOnMainThread(
83                                         mContext,
84                                         () -> { // Check nullability to pass NullAway check
85                                             if (mPreference != null) {
86                                                 mPreference.setVisible(false);
87                                             }
88                                         });
89                                 return;
90                             }
91                             boolean isBtOn = isBluetoothStateOn();
92                             boolean isProfileReady =
93                                     AudioSharingUtils.isAudioSharingProfileReady(mProfileManager);
94                             boolean isBroadcasting = isBroadcasting();
95                             boolean isVisible = isBtOn && isProfileReady && isBroadcasting;
96                             Log.d(
97                                     TAG,
98                                     "updateVisibility, isBtOn = "
99                                             + isBtOn
100                                             + ", isProfileReady = "
101                                             + isProfileReady
102                                             + ", isBroadcasting = "
103                                             + isBroadcasting);
104                             AudioSharingUtils.postOnMainThread(
105                                     mContext,
106                                     () -> { // Check nullability to pass NullAway check
107                                         if (mPreference != null) {
108                                             mPreference.setVisible(isVisible);
109                                         }
110                                     });
111                         });
112     }
113 
114     /**
115      * Triggered when {@link AudioSharingDashboardFragment} receive onAudioSharingProfilesConnected
116      * callbacks.
117      */
onAudioSharingProfilesConnected()118     protected void onAudioSharingProfilesConnected() {}
119 
isBroadcasting()120     protected boolean isBroadcasting() {
121         return mBroadcast != null && mBroadcast.isEnabled(null);
122     }
123 
isBluetoothStateOn()124     protected boolean isBluetoothStateOn() {
125         return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled();
126     }
127 }
128