1 /*
2  * Copyright 2018 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.car.settings.bluetooth;
18 
19 import static android.os.UserManager.DISALLOW_BLUETOOTH;
20 
21 import android.bluetooth.BluetoothAdapter;
22 import android.car.drivingstate.CarUxRestrictions;
23 import android.content.Context;
24 import android.content.pm.PackageManager;
25 import android.os.UserManager;
26 
27 import androidx.annotation.CallSuper;
28 import androidx.annotation.VisibleForTesting;
29 import androidx.preference.Preference;
30 
31 import com.android.car.settings.common.FragmentController;
32 import com.android.car.settings.common.PreferenceController;
33 import com.android.settingslib.bluetooth.BluetoothCallback;
34 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
35 import com.android.settingslib.bluetooth.LocalBluetoothManager;
36 
37 /**
38  * Abstract {@link PreferenceController} that listens to {@link BluetoothCallback} events and
39  * exposes the interface methods for override. It implements a default
40  * {@link #getAvailabilityStatus()} which is {@link #AVAILABLE} when the  system supports
41  * Bluetooth, the current user is not restricted by {@link DISALLOW_BLUETOOTH}, and the default
42  * Bluetooth adapter is enabled.
43  *
44  * @param <V> the upper bound on the type of {@link Preference} on which the controller expects
45  *         to operate.
46  */
47 public abstract class BluetoothPreferenceController<V extends Preference> extends
48         PreferenceController<V> implements BluetoothCallback {
49 
50     protected final LocalBluetoothManager mBluetoothManager;
51     private final UserManager mUserManager;
52 
BluetoothPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)53     public BluetoothPreferenceController(Context context, String preferenceKey,
54             FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
55         super(context, preferenceKey, fragmentController, uxRestrictions);
56         mBluetoothManager = BluetoothUtils.getLocalBtManager(context);
57         mUserManager = context.getSystemService(UserManager.class);
58     }
59 
60     @VisibleForTesting
BluetoothPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions, LocalBluetoothManager localBluetoothManager, UserManager userManager)61     BluetoothPreferenceController(Context context, String preferenceKey,
62             FragmentController fragmentController, CarUxRestrictions uxRestrictions,
63             LocalBluetoothManager localBluetoothManager, UserManager userManager) {
64         super(context, preferenceKey, fragmentController, uxRestrictions);
65         mBluetoothManager = localBluetoothManager;
66         mUserManager = userManager;
67     }
68 
69     /** Returns a {@link UserManager} retrieved with the controller context. **/
getUserManager()70     protected final UserManager getUserManager() {
71         return mUserManager;
72     }
73 
74     /**
75      * Returns a {@link LocalBluetoothManager} retrieved with the controller context. This is
76      * not {@code null} unless {@link #getAvailabilityStatus()} returns
77      * {@link #UNSUPPORTED_ON_DEVICE}.
78      */
getBluetoothManager()79     protected final LocalBluetoothManager getBluetoothManager() {
80         return mBluetoothManager;
81     }
82 
83     @Override
getDefaultAvailabilityStatus()84     protected int getDefaultAvailabilityStatus() {
85         if (!getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
86             return UNSUPPORTED_ON_DEVICE;
87         }
88         if (mUserManager.hasUserRestriction(DISALLOW_BLUETOOTH)) {
89             return DISABLED_FOR_PROFILE;
90         }
91         return BluetoothAdapter.getDefaultAdapter().isEnabled() ? AVAILABLE
92                 : CONDITIONALLY_UNAVAILABLE;
93     }
94 
95     @Override
96     @CallSuper
onStartInternal()97     protected void onStartInternal() {
98         mBluetoothManager.getEventManager().registerCallback(this);
99     }
100 
101     @Override
102     @CallSuper
onStopInternal()103     protected void onStopInternal() {
104         mBluetoothManager.getEventManager().unregisterCallback(this);
105     }
106 
107     @Override
108     @CallSuper
onBluetoothStateChanged(int bluetoothState)109     public void onBluetoothStateChanged(int bluetoothState) {
110         refreshUi();
111     }
112 
113     @Override
onScanningStateChanged(boolean started)114     public void onScanningStateChanged(boolean started) {
115     }
116 
117     @Override
onDeviceAdded(CachedBluetoothDevice cachedDevice)118     public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
119     }
120 
121     @Override
onDeviceDeleted(CachedBluetoothDevice cachedDevice)122     public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
123     }
124 
125     @Override
onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState)126     public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
127     }
128 
129     @Override
onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state)130     public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
131     }
132 
133     @Override
onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile)134     public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
135     }
136 
137     @Override
onAudioModeChanged()138     public void onAudioModeChanged() {
139     }
140 }
141