1 /*
2  * Copyright (C) 2017 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.userlib.CarUserManagerHelper;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.os.Bundle;
28 
29 import androidx.annotation.XmlRes;
30 
31 import com.android.car.settings.R;
32 import com.android.car.settings.common.SettingsFragment;
33 import com.android.car.ui.toolbar.MenuItem;
34 import com.android.settingslib.bluetooth.LocalBluetoothManager;
35 
36 import java.util.Collections;
37 import java.util.List;
38 
39 /**
40  * Main page for Bluetooth settings. It manages the power switch for the Bluetooth adapter. It also
41  * displays paired devices and the entry point for device pairing.
42  */
43 public class BluetoothSettingsFragment extends SettingsFragment {
44 
45     private final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
46     private final IntentFilter mIntentFilter = new IntentFilter(
47             BluetoothAdapter.ACTION_STATE_CHANGED);
48     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
49         @Override
50         public void onReceive(Context context, Intent intent) {
51             int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
52             handleStateChanged(state);
53         }
54     };
55     private final MenuItem.OnClickListener mBluetoothSwitchListener = item -> {
56         item.setEnabled(false);
57         if (item.isChecked()) {
58             mBluetoothAdapter.enable();
59         } else {
60             mBluetoothAdapter.disable();
61         }
62     };
63 
64     private CarUserManagerHelper mCarUserManagerHelper;
65     private LocalBluetoothManager mLocalBluetoothManager;
66     private MenuItem mBluetoothSwitch;
67 
68     @Override
69     @XmlRes
getPreferenceScreenResId()70     protected int getPreferenceScreenResId() {
71         return R.xml.bluetooth_settings_fragment;
72     }
73 
74     @Override
getToolbarMenuItems()75     protected List<MenuItem> getToolbarMenuItems() {
76         return Collections.singletonList(mBluetoothSwitch);
77     }
78 
79     @Override
onCreate(Bundle savedInstanceState)80     public void onCreate(Bundle savedInstanceState) {
81         super.onCreate(savedInstanceState);
82 
83         mBluetoothSwitch = new MenuItem.Builder(getContext())
84                 .setCheckable()
85                 .setOnClickListener(mBluetoothSwitchListener)
86                 .build();
87     }
88 
89     @Override
onAttach(Context context)90     public void onAttach(Context context) {
91         super.onAttach(context);
92         mCarUserManagerHelper = new CarUserManagerHelper(context);
93         mLocalBluetoothManager = BluetoothUtils.getLocalBtManager(context);
94         if (mLocalBluetoothManager == null) {
95             goBack();
96         }
97     }
98 
99     @Override
onStart()100     public void onStart() {
101         super.onStart();
102         requireContext().registerReceiver(mReceiver, mIntentFilter);
103         mLocalBluetoothManager.setForegroundActivity(requireActivity());
104         handleStateChanged(mBluetoothAdapter.getState());
105     }
106 
107     @Override
onStop()108     public void onStop() {
109         super.onStop();
110         requireContext().unregisterReceiver(mReceiver);
111         mLocalBluetoothManager.setForegroundActivity(null);
112     }
113 
isUserRestricted()114     private boolean isUserRestricted() {
115         return mCarUserManagerHelper.isCurrentProcessUserHasRestriction(DISALLOW_BLUETOOTH);
116     }
117 
handleStateChanged(int state)118     private void handleStateChanged(int state) {
119         // Momentarily clear the listener so that we don't update the adapter while trying to
120         // reflect the adapter state.
121         mBluetoothSwitch.setOnClickListener(null);
122         switch (state) {
123             case BluetoothAdapter.STATE_TURNING_ON:
124                 mBluetoothSwitch.setEnabled(false);
125                 mBluetoothSwitch.setChecked(true);
126                 break;
127             case BluetoothAdapter.STATE_ON:
128                 mBluetoothSwitch.setEnabled(!isUserRestricted());
129                 mBluetoothSwitch.setChecked(true);
130                 break;
131             case BluetoothAdapter.STATE_TURNING_OFF:
132                 mBluetoothSwitch.setEnabled(false);
133                 mBluetoothSwitch.setChecked(false);
134                 break;
135             case BluetoothAdapter.STATE_OFF:
136             default:
137                 mBluetoothSwitch.setEnabled(!isUserRestricted());
138                 mBluetoothSwitch.setChecked(false);
139         }
140         mBluetoothSwitch.setOnClickListener(mBluetoothSwitchListener);
141     }
142 }
143