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.bluetooth.BluetoothDevice; 21 import android.content.Context; 22 import android.support.annotation.VisibleForTesting; 23 import android.text.TextUtils; 24 25 import com.android.settings.R; 26 import com.android.settings.widget.SummaryUpdater; 27 import com.android.settingslib.bluetooth.BluetoothCallback; 28 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 29 import com.android.settingslib.bluetooth.LocalBluetoothAdapter; 30 import com.android.settingslib.bluetooth.LocalBluetoothManager; 31 32 import java.util.ArrayList; 33 import java.util.Collection; 34 import java.util.List; 35 import java.util.Set; 36 37 /** 38 * Helper class that listeners to bluetooth callback and notify client when there is update in 39 * bluetooth summary info. 40 */ 41 public final class BluetoothSummaryUpdater extends SummaryUpdater implements BluetoothCallback { 42 43 private final LocalBluetoothManager mBluetoothManager; 44 private final LocalBluetoothAdapter mBluetoothAdapter; 45 46 private boolean mEnabled; 47 private int mConnectionState; 48 BluetoothSummaryUpdater(Context context, OnSummaryChangeListener listener, LocalBluetoothManager bluetoothManager)49 public BluetoothSummaryUpdater(Context context, OnSummaryChangeListener listener, 50 LocalBluetoothManager bluetoothManager) { 51 super(context, listener); 52 mBluetoothManager = bluetoothManager; 53 mBluetoothAdapter = mBluetoothManager != null 54 ? mBluetoothManager.getBluetoothAdapter() : null; 55 } 56 57 @Override onBluetoothStateChanged(int bluetoothState)58 public void onBluetoothStateChanged(int bluetoothState) { 59 mEnabled = bluetoothState == BluetoothAdapter.STATE_ON 60 || bluetoothState == BluetoothAdapter.STATE_TURNING_ON; 61 notifyChangeIfNeeded(); 62 } 63 64 @Override onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state)65 public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { 66 mConnectionState = state; 67 updateConnected(); 68 notifyChangeIfNeeded(); 69 } 70 71 @Override onScanningStateChanged(boolean started)72 public void onScanningStateChanged(boolean started) { 73 } 74 75 @Override onDeviceAdded(CachedBluetoothDevice cachedDevice)76 public void onDeviceAdded(CachedBluetoothDevice cachedDevice) { 77 } 78 79 @Override onDeviceDeleted(CachedBluetoothDevice cachedDevice)80 public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) { 81 } 82 83 @Override onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState)84 public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) { 85 } 86 87 @Override register(boolean listening)88 public void register(boolean listening) { 89 if (mBluetoothAdapter == null) { 90 return; 91 } 92 if (listening) { 93 mEnabled = mBluetoothAdapter.isEnabled(); 94 mConnectionState = mBluetoothAdapter.getConnectionState(); 95 notifyChangeIfNeeded(); 96 mBluetoothManager.getEventManager().registerCallback(this); 97 } else { 98 mBluetoothManager.getEventManager().unregisterCallback(this); 99 } 100 } 101 102 @Override getSummary()103 public String getSummary() { 104 if (!mEnabled) { 105 return mContext.getString(R.string.bluetooth_disabled); 106 } 107 switch (mConnectionState) { 108 case BluetoothAdapter.STATE_CONNECTED: 109 return getConnectedDeviceSummary(); 110 case BluetoothAdapter.STATE_CONNECTING: 111 return mContext.getString(R.string.bluetooth_connecting); 112 case BluetoothAdapter.STATE_DISCONNECTING: 113 return mContext.getString(R.string.bluetooth_disconnecting); 114 default: 115 return mContext.getString(R.string.disconnected); 116 } 117 } 118 updateConnected()119 private void updateConnected() { 120 if (mBluetoothAdapter == null) { 121 return; 122 } 123 // Make sure our connection state is up to date. 124 int state = mBluetoothAdapter.getConnectionState(); 125 if (state != mConnectionState) { 126 mConnectionState = state; 127 return; 128 } 129 final Collection<CachedBluetoothDevice> devices = getDevices(); 130 if (devices == null) { 131 mConnectionState = BluetoothAdapter.STATE_DISCONNECTED; 132 return; 133 } 134 if (mConnectionState == BluetoothAdapter.STATE_CONNECTED) { 135 CachedBluetoothDevice connectedDevice = null; 136 for (CachedBluetoothDevice device : devices) { 137 if (device.isConnected()) { 138 connectedDevice = device; 139 break; 140 } 141 } 142 if (connectedDevice == null) { 143 // If somehow we think we are connected, but have no connected devices, we 144 // aren't connected. 145 mConnectionState = BluetoothAdapter.STATE_DISCONNECTED; 146 } 147 } 148 } 149 getDevices()150 private Collection<CachedBluetoothDevice> getDevices() { 151 return mBluetoothManager != null 152 ? mBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy() 153 : null; 154 } 155 156 @VisibleForTesting getConnectedDeviceSummary()157 String getConnectedDeviceSummary() { 158 String deviceName = null; 159 int count = 0; 160 final Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices(); 161 if (devices == null || devices.isEmpty()) { 162 return null; 163 } 164 165 for (BluetoothDevice device : devices) { 166 if (device.isConnected()) { 167 deviceName = device.getName(); 168 count++; 169 if (count > 1) { 170 break; 171 } 172 } 173 } 174 175 return count > 1 ? mContext.getString(R.string.bluetooth_connected_multiple_devices_summary) 176 : mContext.getString(R.string.bluetooth_connected_summary, deviceName); 177 } 178 179 } 180