• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.car.settings.bluetooth;
17 
18 import android.bluetooth.BluetoothAdapter;
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.os.Bundle;
24 import android.support.v4.widget.SwipeRefreshLayout;
25 import android.view.View;
26 import android.widget.ProgressBar;
27 import android.widget.Switch;
28 import android.widget.TextView;
29 import android.widget.ViewSwitcher;
30 
31 import androidx.car.widget.PagedListView;
32 
33 import com.android.car.settings.R;
34 import com.android.car.settings.common.BaseFragment;
35 import com.android.car.settings.common.Logger;
36 import com.android.settingslib.bluetooth.BluetoothCallback;
37 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
38 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
39 import com.android.settingslib.bluetooth.LocalBluetoothManager;
40 
41 /**
42  * Hosts Bluetooth related preferences.
43  */
44 public class BluetoothSettingsFragment extends BaseFragment implements BluetoothCallback {
45     private static final Logger LOG = new Logger(BluetoothSettingsFragment.class);
46 
47     private SwipeRefreshLayout mSwipeRefreshLayout;
48     private Switch mBluetoothSwitch;
49     private ProgressBar mProgressBar;
50     private PagedListView mDeviceListView;
51     private ViewSwitcher mViewSwitcher;
52     private TextView mMessageView;
53     private BluetoothDeviceListAdapter mDeviceAdapter;
54     private LocalBluetoothAdapter mLocalAdapter;
55     private LocalBluetoothManager mLocalManager;
56 
57     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
58         @Override
59         public void onReceive(Context context, Intent intent) {
60             if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent.getAction())) {
61                 setProgressBarVisible(true);
62                 mBluetoothSwitch.setChecked(true);
63                 if (mViewSwitcher.getCurrentView() != mSwipeRefreshLayout) {
64                     mViewSwitcher.showPrevious();
65                 }
66             } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())) {
67                 setProgressBarVisible(false);
68             }
69         }
70     };
71 
getInstance()72     public static BluetoothSettingsFragment getInstance() {
73         BluetoothSettingsFragment bluetoothSettingsFragment = new BluetoothSettingsFragment();
74         Bundle bundle = BaseFragment.getBundle();
75         bundle.putInt(EXTRA_TITLE_ID, R.string.bluetooth_settings);
76         bundle.putInt(EXTRA_LAYOUT, R.layout.bluetooth_list);
77         bundle.putInt(EXTRA_ACTION_BAR_LAYOUT, R.layout.action_bar_with_toggle);
78         bluetoothSettingsFragment.setArguments(bundle);
79         return bluetoothSettingsFragment;
80     }
81 
82     @Override
onActivityCreated(Bundle savedInstanceState)83     public void onActivityCreated(Bundle savedInstanceState) {
84         super.onActivityCreated(savedInstanceState);
85         mBluetoothSwitch = getActivity().findViewById(R.id.toggle_switch);
86         mSwipeRefreshLayout = getActivity().findViewById(R.id.swiperefresh);
87         mSwipeRefreshLayout.setSize(SwipeRefreshLayout.LARGE);
88         mSwipeRefreshLayout.setOnRefreshListener(
89                 new SwipeRefreshLayout.OnRefreshListener() {
90                     @Override
91                     public void onRefresh() {
92                         mSwipeRefreshLayout.setRefreshing(false);
93                         if (mLocalAdapter.isDiscovering()) {
94                             mLocalAdapter.cancelDiscovery();
95                         }
96                         mDeviceAdapter.reset();
97                     }
98                 }
99         );
100 
101         mBluetoothSwitch.setOnCheckedChangeListener((v, isChecked) -> {
102                 if (mBluetoothSwitch.isChecked()) {
103                     // bt scan was turned on at state listener, when state is on.
104                     mLocalAdapter.setBluetoothEnabled(true);
105                 } else {
106                     mLocalAdapter.stopScanning();
107                     mLocalAdapter.setBluetoothEnabled(false);
108                 }
109             });
110 
111         mProgressBar = getView().findViewById(R.id.bt_search_progress);
112         mDeviceListView = getView().findViewById(R.id.list);
113         mViewSwitcher = getView().findViewById(R.id.view_switcher);
114         mMessageView = getView().findViewById(R.id.bt_message);
115 
116         mLocalManager =
117                 LocalBluetoothManager.getInstance(getContext(), /* onInitCallback= */ null);
118         if (mLocalManager == null) {
119             LOG.e("Bluetooth is not supported on this device");
120             return;
121         }
122         mLocalAdapter = mLocalManager.getBluetoothAdapter();
123     }
124 
125     @Override
onStart()126     public void onStart() {
127         super.onStart();
128         if (mLocalManager == null) {
129             return;
130         }
131         IntentFilter filter = new IntentFilter();
132         filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
133         filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
134         getActivity().registerReceiver(mBroadcastReceiver, filter);
135 
136         mLocalManager.setForegroundActivity(getActivity());
137         mLocalManager.getEventManager().registerCallback(this);
138         mBluetoothSwitch.setChecked(mLocalAdapter.isEnabled());
139         if (mLocalAdapter.isEnabled()) {
140             setProgressBarVisible(true);
141             mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
142             mLocalAdapter.startScanning(true);
143             if (mViewSwitcher.getCurrentView() != mSwipeRefreshLayout) {
144                 mViewSwitcher.showPrevious();
145             }
146         } else {
147             setProgressBarVisible(false);
148             if (mViewSwitcher.getCurrentView() != mMessageView) {
149                 mViewSwitcher.showNext();
150             }
151         }
152         mDeviceAdapter = new BluetoothDeviceListAdapter(
153                 getContext() , mLocalManager, getFragmentController());
154         mDeviceListView.setAdapter(mDeviceAdapter);
155         mDeviceAdapter.start();
156     }
157 
158     @Override
onStop()159     public void onStop() {
160         super.onStop();
161         if (mLocalManager == null) {
162             return;
163         }
164         getActivity().unregisterReceiver(mBroadcastReceiver);
165         mDeviceAdapter.stop();
166         mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
167         mLocalManager.setForegroundActivity(null);
168         mLocalAdapter.stopScanning();
169         mLocalManager.getEventManager().unregisterCallback(this);
170     }
171 
172     @Override
onBluetoothStateChanged(int bluetoothState)173     public void onBluetoothStateChanged(int bluetoothState) {
174         switch (bluetoothState) {
175             case BluetoothAdapter.STATE_OFF:
176                 setProgressBarVisible(false);
177                 mBluetoothSwitch.setChecked(false);
178                 if (mViewSwitcher.getCurrentView() != mMessageView) {
179                     mViewSwitcher.showNext();
180                 }
181                 break;
182             case BluetoothAdapter.STATE_ON:
183             case BluetoothAdapter.STATE_TURNING_ON:
184                 setProgressBarVisible(true);
185                 mBluetoothSwitch.setChecked(true);
186                 if (mViewSwitcher.getCurrentView() != mSwipeRefreshLayout) {
187                         mViewSwitcher.showPrevious();
188                 }
189                 break;
190             case BluetoothAdapter.STATE_TURNING_OFF:
191                 setProgressBarVisible(true);
192                 break;
193         }
194     }
195 
196     @Override
onScanningStateChanged(boolean started)197     public void onScanningStateChanged(boolean started) {
198         if (!started) {
199             setProgressBarVisible(false);
200         }
201     }
202 
203     @Override
onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState)204     public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
205         // no-op
206     }
207 
208     @Override
onDeviceAdded(CachedBluetoothDevice cachedDevice)209     public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
210         // no-op
211     }
212 
213     @Override
onDeviceDeleted(CachedBluetoothDevice cachedDevice)214     public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
215         // no-op
216     }
217 
218     @Override
onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state)219     public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
220         // no-op
221     }
222 
223     @Override
onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile)224     public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
225         // no-op
226     }
227 
228     @Override
onAudioModeChanged()229     public void onAudioModeChanged() {
230         // no-op
231     }
232 
setProgressBarVisible(boolean visible)233     private  void setProgressBarVisible(boolean visible) {
234         if (mProgressBar != null) {
235             mProgressBar.setVisibility(visible ? View.VISIBLE : View.GONE);
236         }
237     }
238 }
239