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.settings.bluetooth; 18 19 import android.bluetooth.BluetoothAdapter; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 25 import androidx.annotation.VisibleForTesting; 26 27 /** Helper class, intended to be used by an Activity, to keep the local Bluetooth adapter in 28 * discoverable mode indefinitely. By default setting the scan mode to 29 * BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE will time out after some time, but some 30 * Bluetooth settings pages would like to keep the device discoverable as long as the page is 31 * visible. */ 32 public class AlwaysDiscoverable extends BroadcastReceiver { 33 private static final String TAG = "AlwaysDiscoverable"; 34 35 private Context mContext; 36 private BluetoothAdapter mBluetoothAdapter; 37 private IntentFilter mIntentFilter; 38 39 @VisibleForTesting 40 boolean mStarted; 41 AlwaysDiscoverable(Context context)42 public AlwaysDiscoverable(Context context) { 43 mContext = context; 44 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 45 mIntentFilter = new IntentFilter(); 46 mIntentFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); 47 } 48 49 /** After calling start(), consumers should make a matching call to stop() when they no longer 50 * wish to enforce discoverable mode. */ start()51 public void start() { 52 if (mStarted) { 53 return; 54 } 55 mContext.registerReceiver(this, mIntentFilter); 56 mStarted = true; 57 if (mBluetoothAdapter.getScanMode() 58 != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { 59 mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); 60 } 61 } 62 stop()63 public void stop() { 64 if (!mStarted) { 65 return; 66 } 67 mContext.unregisterReceiver(this); 68 mStarted = false; 69 mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE); 70 } 71 72 @Override onReceive(Context context, Intent intent)73 public void onReceive(Context context, Intent intent) { 74 String action = intent.getAction(); 75 if (action != BluetoothAdapter.ACTION_SCAN_MODE_CHANGED) { 76 return; 77 } 78 if (mBluetoothAdapter.getScanMode() 79 != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { 80 mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); 81 } 82 } 83 } 84