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