1436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby/* 2436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Copyright (C) 2011 The Android Open Source Project 3436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * 4436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Licensed under the Apache License, Version 2.0 (the "License"); 5436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * you may not use this file except in compliance with the License. 6436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * You may obtain a copy of the License at 7436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * 8436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * http://www.apache.org/licenses/LICENSE-2.0 9436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * 10436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Unless required by applicable law or agreed to in writing, software 11436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * distributed under the License is distributed on an "AS IS" BASIS, 12436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * See the License for the specific language governing permissions and 14436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * limitations under the License. 15436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby */ 16436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 17436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambypackage com.android.settings.bluetooth; 18436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 19436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.bluetooth.BluetoothAdapter; 20436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.bluetooth.BluetoothDevice; 21436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.bluetooth.BluetoothProfile; 22436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.content.Context; 23436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.os.ParcelUuid; 24436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.util.Log; 25436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 26436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport java.util.Set; 27436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 28436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby/** 29436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * LocalBluetoothAdapter provides an interface between the Settings app 30436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * and the functionality of the local {@link BluetoothAdapter}, specifically 31436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * those related to state transitions of the adapter itself. 32436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * 33436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * <p>Connection and bonding state changes affecting specific devices 34436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * are handled by {@link CachedBluetoothDeviceManager}, 35436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * {@link BluetoothEventManager}, and {@link LocalBluetoothProfileManager}. 36436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby */ 37436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambypublic final class LocalBluetoothAdapter { 38436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private static final String TAG = "LocalBluetoothAdapter"; 39436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 40436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby /** This class does not allow direct access to the BluetoothAdapter. */ 41436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private final BluetoothAdapter mAdapter; 42436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 43436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private LocalBluetoothProfileManager mProfileManager; 44436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 45436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private static LocalBluetoothAdapter sInstance; 46436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 47436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private int mState = BluetoothAdapter.ERROR; 48436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 49436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private static final int SCAN_EXPIRATION_MS = 5 * 60 * 1000; // 5 mins 50436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 51436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private long mLastScan; 52436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 53436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private LocalBluetoothAdapter(BluetoothAdapter adapter) { 54436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mAdapter = adapter; 55436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 56436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 57436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby void setProfileManager(LocalBluetoothProfileManager manager) { 58436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mProfileManager = manager; 59436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 60436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 61436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby /** 62436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Get the singleton instance of the LocalBluetoothAdapter. If this device 63436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * doesn't support Bluetooth, then null will be returned. Callers must be 64436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * prepared to handle a null return value. 65436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * @return the LocalBluetoothAdapter object, or null if not supported 66436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby */ 67436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby static synchronized LocalBluetoothAdapter getInstance() { 68436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (sInstance == null) { 69436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 70436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (adapter != null) { 71436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby sInstance = new LocalBluetoothAdapter(adapter); 72436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 73436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 74436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 75436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return sInstance; 76436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 77436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 78436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby // Pass-through BluetoothAdapter methods that we can intercept if necessary 79436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 80436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby void cancelDiscovery() { 81436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mAdapter.cancelDiscovery(); 82436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 83436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 84436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby boolean enable() { 85436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return mAdapter.enable(); 86436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 87436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 88436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby boolean disable() { 89436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return mAdapter.disable(); 90436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 91436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 92436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby void getProfileProxy(Context context, 93436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby BluetoothProfile.ServiceListener listener, int profile) { 94436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mAdapter.getProfileProxy(context, listener, profile); 95436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 96436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 97436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby Set<BluetoothDevice> getBondedDevices() { 98436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return mAdapter.getBondedDevices(); 99436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 100436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 101436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby String getName() { 102436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return mAdapter.getName(); 103436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 104436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 105436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby int getScanMode() { 106436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return mAdapter.getScanMode(); 107436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 108436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 109436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby int getState() { 110436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return mAdapter.getState(); 111436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 112436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 113436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby ParcelUuid[] getUuids() { 114436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return mAdapter.getUuids(); 115436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 116436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 117436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby boolean isDiscovering() { 118436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return mAdapter.isDiscovering(); 119436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 120436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 121436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby boolean isEnabled() { 122436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return mAdapter.isEnabled(); 123436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 124436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 125436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby void setDiscoverableTimeout(int timeout) { 126436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mAdapter.setDiscoverableTimeout(timeout); 127436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 128436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 129436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby void setName(String name) { 130436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mAdapter.setName(name); 131436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 132436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 133436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby void setScanMode(int mode) { 134436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mAdapter.setScanMode(mode); 135436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 136436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 137436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby boolean setScanMode(int mode, int duration) { 138436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return mAdapter.setScanMode(mode, duration); 139436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 140436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 141436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby void startScanning(boolean force) { 142436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby // Only start if we're not already scanning 143436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (!mAdapter.isDiscovering()) { 144436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (!force) { 145436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby // Don't scan more than frequently than SCAN_EXPIRATION_MS, 146436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby // unless forced 147436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) { 148436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return; 149436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 150436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 151436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby // If we are playing music, don't scan unless forced. 152436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby A2dpProfile a2dp = mProfileManager.getA2dpProfile(); 153436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (a2dp != null && a2dp.isA2dpPlaying()) { 154436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return; 155436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 156436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 157436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 158436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (mAdapter.startDiscovery()) { 159436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mLastScan = System.currentTimeMillis(); 160436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 161436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 162436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 163436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 164436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby void stopScanning() { 165436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (mAdapter.isDiscovering()) { 166436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mAdapter.cancelDiscovery(); 167436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 168436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 169436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 170436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby public synchronized int getBluetoothState() { 171436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby // Always sync state, in case it changed while paused 172436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby syncBluetoothState(); 173436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return mState; 174436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 175436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 176436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby synchronized void setBluetoothStateInt(int state) { 177436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mState = state; 178436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 179436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (state == BluetoothAdapter.STATE_ON) { 180436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby // if mProfileManager hasn't been constructed yet, it will 181436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby // get the adapter UUIDs in its constructor when it is. 182436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (mProfileManager != null) { 183436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mProfileManager.setBluetoothStateOn(); 184436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 185436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 186436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 187436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 188436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby // Returns true if the state changed; false otherwise. 189436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby boolean syncBluetoothState() { 190436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby int currentState = mAdapter.getState(); 191436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (currentState != mState) { 192436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby setBluetoothStateInt(mAdapter.getState()); 193436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return true; 194436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 195436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return false; 196436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 197436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 198436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby public void setBluetoothEnabled(boolean enabled) { 199436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby boolean success = enabled 200436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby ? mAdapter.enable() 201436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby : mAdapter.disable(); 202436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 203436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (success) { 204436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby setBluetoothStateInt(enabled 205436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby ? BluetoothAdapter.STATE_TURNING_ON 206436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby : BluetoothAdapter.STATE_TURNING_OFF); 207436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } else { 208436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (Utils.V) { 209436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby Log.v(TAG, "setBluetoothEnabled call, manager didn't return " + 210436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby "success for enabled: " + enabled); 211436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 212436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 213436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby syncBluetoothState(); 214436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 215436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 216436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby} 217