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.util.Log; 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.Collection; 33 import java.util.Set; 34 35 /** 36 * Helper class that listeners to bluetooth callback and notify client when there is update in 37 * bluetooth summary info. 38 */ 39 public final class BluetoothSummaryUpdater extends SummaryUpdater implements BluetoothCallback { 40 private static final String TAG = "BluetoothSummaryUpdater"; 41 42 private final LocalBluetoothManager mBluetoothManager; 43 private final LocalBluetoothAdapter mBluetoothAdapter; 44 45 public BluetoothSummaryUpdater(Context context, OnSummaryChangeListener listener, 46 LocalBluetoothManager bluetoothManager) { 47 super(context, listener); 48 mBluetoothManager = bluetoothManager; 49 mBluetoothAdapter = mBluetoothManager != null 50 ? mBluetoothManager.getBluetoothAdapter() : null; 51 } 52 53 @Override 54 public void onBluetoothStateChanged(int bluetoothState) { 55 notifyChangeIfNeeded(); 56 } 57 58 @Override 59 public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { 60 notifyChangeIfNeeded(); 61 } 62 63 @Override 64 public void onScanningStateChanged(boolean started) { 65 } 66 67 @Override 68 public void onDeviceAdded(CachedBluetoothDevice cachedDevice) { 69 } 70 71 @Override 72 public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) { 73 } 74 75 @Override 76 public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) { 77 } 78 79 @Override 80 public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) { 81 } 82 83 @Override 84 public void onAudioModeChanged() { 85 } 86 87 @Override 88 public void register(boolean listening) { 89 if (mBluetoothAdapter == null) { 90 return; 91 } 92 if (listening) { 93 notifyChangeIfNeeded(); 94 mBluetoothManager.getEventManager().registerCallback(this); 95 } else { 96 mBluetoothManager.getEventManager().unregisterCallback(this); 97 } 98 } 99 100 @Override 101 public String getSummary() { 102 if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { 103 return mContext.getString(R.string.bluetooth_disabled); 104 } 105 switch (mBluetoothAdapter.getConnectionState()) { 106 case BluetoothAdapter.STATE_CONNECTED: 107 return getConnectedDeviceSummary(); 108 case BluetoothAdapter.STATE_CONNECTING: 109 return mContext.getString(R.string.bluetooth_connecting); 110 case BluetoothAdapter.STATE_DISCONNECTING: 111 return mContext.getString(R.string.bluetooth_disconnecting); 112 default: 113 return mContext.getString(R.string.disconnected); 114 } 115 } 116 117 @VisibleForTesting 118 String getConnectedDeviceSummary() { 119 String deviceName = null; 120 int count = 0; 121 final Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices(); 122 if (devices == null) { 123 Log.e(TAG, "getConnectedDeviceSummary, bonded devices are null"); 124 return mContext.getString(R.string.bluetooth_disabled); 125 } else if (devices.isEmpty()) { 126 Log.e(TAG, "getConnectedDeviceSummary, no bonded devices"); 127 return mContext.getString(R.string.disconnected); 128 } 129 for (BluetoothDevice device : devices) { 130 if (device.isConnected()) { 131 deviceName = device.getName(); 132 count++; 133 if (count > 1) { 134 break; 135 } 136 } 137 } 138 if (deviceName == null) { 139 Log.e(TAG, "getConnectedDeviceSummary, deviceName is null, numBondedDevices=" 140 + devices.size()); 141 for (BluetoothDevice device : devices) { 142 Log.e(TAG, "getConnectedDeviceSummary, device=" + device.getName() + "[" 143 + device.getAddress() + "]" + ", isConnected=" + device.isConnected()); 144 } 145 return mContext.getString(R.string.disconnected); 146 } 147 return count > 1 ? mContext.getString(R.string.bluetooth_connected_multiple_devices_summary) 148 : mContext.getString(R.string.bluetooth_connected_summary, deviceName); 149 } 150 151 } 152