Home | History | Annotate | Download | only in bluetooth
      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 
     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
     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
    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
    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
    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
    197     public void onScanningStateChanged(boolean started) {
    198         if (!started) {
    199             setProgressBarVisible(false);
    200         }
    201     }
    202 
    203     @Override
    204     public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
    205         // no-op
    206     }
    207 
    208     @Override
    209     public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
    210         // no-op
    211     }
    212 
    213     @Override
    214     public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
    215         // no-op
    216     }
    217 
    218     @Override
    219     public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
    220         // no-op
    221     }
    222 
    223     @Override
    224     public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
    225         // no-op
    226     }
    227 
    228     @Override
    229     public void onAudioModeChanged() {
    230         // no-op
    231     }
    232 
    233     private  void setProgressBarVisible(boolean visible) {
    234         if (mProgressBar != null) {
    235             mProgressBar.setVisibility(visible ? View.VISIBLE : View.GONE);
    236         }
    237     }
    238 }
    239