1 /* 2 * Copyright 2018 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.settingslib.media; 17 18 import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_TRANSFER; 19 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.bluetooth.BluetoothClass; 23 import android.bluetooth.BluetoothDevice; 24 import android.bluetooth.BluetoothHearingAid; 25 import android.content.Context; 26 import android.graphics.drawable.Drawable; 27 import android.media.AudioManager; 28 import android.media.MediaRoute2Info; 29 import android.media.RouteListingPreference; 30 31 import com.android.settingslib.R; 32 import com.android.settingslib.bluetooth.BluetoothUtils; 33 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 34 35 /** 36 * BluetoothMediaDevice extends MediaDevice to represents Bluetooth device. 37 */ 38 public class BluetoothMediaDevice extends MediaDevice { 39 40 private static final String TAG = "BluetoothMediaDevice"; 41 42 private final CachedBluetoothDevice mCachedDevice; 43 private final AudioManager mAudioManager; 44 BluetoothMediaDevice( @onNull Context context, @NonNull CachedBluetoothDevice device, @Nullable MediaRoute2Info info, @Nullable RouteListingPreference.Item item)45 BluetoothMediaDevice( 46 @NonNull Context context, 47 @NonNull CachedBluetoothDevice device, 48 @Nullable MediaRoute2Info info, 49 @Nullable RouteListingPreference.Item item) { 50 super(context, info, item); 51 mCachedDevice = device; 52 mAudioManager = context.getSystemService(AudioManager.class); 53 initDeviceRecord(); 54 } 55 56 @Override getName()57 public String getName() { 58 return mCachedDevice.getName(); 59 } 60 61 @Override getSummary()62 public String getSummary() { 63 return isConnected() || mCachedDevice.isBusy() 64 ? mCachedDevice.getConnectionSummary() 65 : mContext.getString(R.string.bluetooth_disconnected); 66 } 67 68 @Override getSummaryForTv(int lowBatteryColorRes)69 public CharSequence getSummaryForTv(int lowBatteryColorRes) { 70 return isConnected() || mCachedDevice.isBusy() 71 ? mCachedDevice.getTvConnectionSummary(lowBatteryColorRes) 72 : mContext.getString(R.string.bluetooth_saved_device); 73 } 74 75 @Override getSelectionBehavior()76 public int getSelectionBehavior() { 77 // We don't allow apps to override the selection behavior of system routes. 78 return SELECTION_BEHAVIOR_TRANSFER; 79 } 80 81 @Override getIcon()82 public Drawable getIcon() { 83 return BluetoothUtils.isAdvancedUntetheredDevice(mCachedDevice.getDevice()) 84 ? mContext.getDrawable(R.drawable.ic_earbuds_advanced) 85 : BluetoothUtils.getBtClassDrawableWithDescription(mContext, mCachedDevice).first; 86 } 87 88 @Override getIconWithoutBackground()89 public Drawable getIconWithoutBackground() { 90 return BluetoothUtils.isAdvancedUntetheredDevice(mCachedDevice.getDevice()) 91 ? mContext.getDrawable(R.drawable.ic_earbuds_advanced) 92 : BluetoothUtils.getBtClassDrawableWithDescription(mContext, mCachedDevice).first; 93 } 94 95 @Override getId()96 public String getId() { 97 if (mCachedDevice.isHearingAidDevice()) { 98 if (mCachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) { 99 return Long.toString(mCachedDevice.getHiSyncId()); 100 } 101 } 102 return mCachedDevice.getAddress(); 103 } 104 105 /** 106 * Get current CachedBluetoothDevice 107 */ getCachedDevice()108 public CachedBluetoothDevice getCachedDevice() { 109 return mCachedDevice; 110 } 111 112 @Override isCarKitDevice()113 protected boolean isCarKitDevice() { 114 final BluetoothClass bluetoothClass = mCachedDevice.getDevice().getBluetoothClass(); 115 if (bluetoothClass != null) { 116 switch (bluetoothClass.getDeviceClass()) { 117 // Both are common CarKit class 118 case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: 119 case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: 120 return true; 121 } 122 } 123 return false; 124 } 125 126 @Override isFastPairDevice()127 public boolean isFastPairDevice() { 128 return mCachedDevice != null 129 && BluetoothUtils.getBooleanMetaData( 130 mCachedDevice.getDevice(), BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET); 131 } 132 133 @Override isMutingExpectedDevice()134 public boolean isMutingExpectedDevice() { 135 return mAudioManager.getMutingExpectedDevice() != null && mCachedDevice.getAddress().equals( 136 mAudioManager.getMutingExpectedDevice().getAddress()); 137 } 138 139 @Override isConnected()140 public boolean isConnected() { 141 return mCachedDevice.getBondState() == BluetoothDevice.BOND_BONDED 142 && mCachedDevice.isConnected(); 143 } 144 } 145