1 /* 2 * Copyright 2024 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 android.media.AudioDeviceInfo.TYPE_BLE_HEADSET; 19 import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_SCO; 20 import static android.media.AudioDeviceInfo.TYPE_BUILTIN_MIC; 21 import static android.media.AudioDeviceInfo.TYPE_USB_ACCESSORY; 22 import static android.media.AudioDeviceInfo.TYPE_USB_DEVICE; 23 import static android.media.AudioDeviceInfo.TYPE_USB_HEADSET; 24 import static android.media.AudioDeviceInfo.TYPE_WIRED_HEADSET; 25 26 import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_TRANSFER; 27 28 import android.content.Context; 29 import android.graphics.drawable.Drawable; 30 import android.media.AudioDeviceInfo.AudioDeviceType; 31 32 import androidx.annotation.NonNull; 33 import androidx.annotation.Nullable; 34 import androidx.annotation.VisibleForTesting; 35 36 import com.android.settingslib.R; 37 38 /** {@link MediaDevice} implementation that represents an input device. */ 39 public class InputMediaDevice extends MediaDevice { 40 41 private static final String TAG = "InputMediaDevice"; 42 43 private final String mId; 44 45 private final @AudioDeviceType int mAudioDeviceInfoType; 46 47 private final int mMaxVolume; 48 49 private final int mCurrentVolume; 50 51 private final boolean mIsVolumeFixed; 52 53 private final String mProductName; 54 InputMediaDevice( @onNull Context context, @NonNull String id, @AudioDeviceType int audioDeviceInfoType, int maxVolume, int currentVolume, boolean isVolumeFixed, @Nullable String productName)55 private InputMediaDevice( 56 @NonNull Context context, 57 @NonNull String id, 58 @AudioDeviceType int audioDeviceInfoType, 59 int maxVolume, 60 int currentVolume, 61 boolean isVolumeFixed, 62 @Nullable String productName) { 63 super(context, /* info= */ null, /* item= */ null); 64 mId = id; 65 mAudioDeviceInfoType = audioDeviceInfoType; 66 mMaxVolume = maxVolume; 67 mCurrentVolume = currentVolume; 68 mIsVolumeFixed = isVolumeFixed; 69 mProductName = productName; 70 initDeviceRecord(); 71 } 72 73 @Nullable create( @onNull Context context, @NonNull String id, @AudioDeviceType int audioDeviceInfoType, int maxVolume, int currentVolume, boolean isVolumeFixed, @Nullable String productName)74 public static InputMediaDevice create( 75 @NonNull Context context, 76 @NonNull String id, 77 @AudioDeviceType int audioDeviceInfoType, 78 int maxVolume, 79 int currentVolume, 80 boolean isVolumeFixed, 81 @Nullable String productName) { 82 if (!isSupportedInputDevice(audioDeviceInfoType)) { 83 return null; 84 } 85 86 return new InputMediaDevice( 87 context, 88 id, 89 audioDeviceInfoType, 90 maxVolume, 91 currentVolume, 92 isVolumeFixed, 93 productName); 94 } 95 getAudioDeviceInfoType()96 public @AudioDeviceType int getAudioDeviceInfoType() { 97 return mAudioDeviceInfoType; 98 } 99 isSupportedInputDevice(@udioDeviceType int audioDeviceInfoType)100 public static boolean isSupportedInputDevice(@AudioDeviceType int audioDeviceInfoType) { 101 return switch (audioDeviceInfoType) { 102 case TYPE_BUILTIN_MIC, 103 TYPE_WIRED_HEADSET, 104 TYPE_USB_DEVICE, 105 TYPE_USB_HEADSET, 106 TYPE_USB_ACCESSORY, 107 TYPE_BLUETOOTH_SCO, 108 TYPE_BLE_HEADSET -> 109 true; 110 default -> false; 111 }; 112 } 113 114 @Nullable getProductName()115 public String getProductName() { 116 return mProductName; 117 } 118 119 @Override getName()120 public @NonNull String getName() { 121 return switch (mAudioDeviceInfoType) { 122 case TYPE_WIRED_HEADSET -> 123 mContext.getString(R.string.media_transfer_wired_device_mic_name); 124 case TYPE_USB_DEVICE, TYPE_USB_HEADSET, TYPE_USB_ACCESSORY -> 125 // The product name is assumed to be a well-formed string if it's not null. 126 mProductName != null 127 ? mProductName 128 : mContext.getString(R.string.media_transfer_usb_device_mic_name); 129 case TYPE_BLUETOOTH_SCO, TYPE_BLE_HEADSET -> 130 mProductName != null 131 ? mProductName 132 : mContext.getString(R.string.media_transfer_bt_device_mic_name); 133 default -> mContext.getString(R.string.media_transfer_this_device_name_desktop); 134 }; 135 } 136 137 @Override 138 public @SelectionBehavior int getSelectionBehavior() { 139 // We don't allow apps to override the selection behavior of system routes. 140 return SELECTION_BEHAVIOR_TRANSFER; 141 } 142 143 @Override 144 public @NonNull String getSummary() { 145 return ""; 146 } 147 148 @Override 149 public @Nullable Drawable getIcon() { 150 return getIconWithoutBackground(); 151 } 152 153 @Override 154 public @Nullable Drawable getIconWithoutBackground() { 155 return mContext.getDrawable(getDrawableResId()); 156 } 157 158 @VisibleForTesting 159 int getDrawableResId() { 160 return R.drawable.ic_media_microphone; 161 } 162 163 @Override 164 public @NonNull String getId() { 165 return mId; 166 } 167 168 @Override 169 public boolean isConnected() { 170 // Indicating if the device is connected and thus showing the status of STATE_CONNECTED. 171 // Upon creation, this device is already connected. 172 return true; 173 } 174 175 @Override 176 public int getMaxVolume() { 177 return mMaxVolume; 178 } 179 180 @Override 181 public int getCurrentVolume() { 182 return mCurrentVolume; 183 } 184 185 @Override 186 public boolean isVolumeFixed() { 187 return mIsVolumeFixed; 188 } 189 } 190