1 /* 2 * Copyright (C) 2022 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.settingslib.media; 18 19 import static android.media.AudioDeviceInfo.AudioDeviceType; 20 import static android.media.AudioDeviceInfo.TYPE_BUILTIN_SPEAKER; 21 import static android.media.AudioDeviceInfo.TYPE_DOCK; 22 import static android.media.AudioDeviceInfo.TYPE_HDMI; 23 import static android.media.AudioDeviceInfo.TYPE_HDMI_ARC; 24 import static android.media.AudioDeviceInfo.TYPE_HDMI_EARC; 25 import static android.media.AudioDeviceInfo.TYPE_USB_ACCESSORY; 26 import static android.media.AudioDeviceInfo.TYPE_USB_DEVICE; 27 import static android.media.AudioDeviceInfo.TYPE_USB_HEADSET; 28 import static android.media.AudioDeviceInfo.TYPE_WIRED_HEADPHONES; 29 import static android.media.AudioDeviceInfo.TYPE_WIRED_HEADSET; 30 31 import android.annotation.DrawableRes; 32 import android.annotation.SuppressLint; 33 import android.content.Context; 34 import android.content.pm.PackageManager; 35 import android.graphics.drawable.Drawable; 36 import android.media.MediaRoute2Info; 37 import android.os.SystemProperties; 38 import android.util.SparseIntArray; 39 40 import androidx.annotation.NonNull; 41 42 import com.android.internal.annotations.VisibleForTesting; 43 import com.android.settingslib.R; 44 import com.android.settingslib.media.flags.Flags; 45 46 import java.util.Arrays; 47 import java.util.Objects; 48 49 /** A util class to get the appropriate icon for different device types. */ 50 public class DeviceIconUtil { 51 52 private static final SparseIntArray AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE = new SparseIntArray(); 53 54 private final boolean mIsTv; 55 private final boolean mIsTablet; 56 private final Context mContext; DeviceIconUtil(@onNull Context context)57 public DeviceIconUtil(@NonNull Context context) { 58 mContext = Objects.requireNonNull(context); 59 mIsTv = 60 mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK) 61 && Flags.enableTvMediaOutputDialog(); 62 mIsTablet = 63 Arrays.asList(SystemProperties.get("ro.build.characteristics").split(",")) 64 .contains("tablet"); 65 } 66 67 @VisibleForTesting DeviceIconUtil(boolean isTv)68 /* package */ DeviceIconUtil(boolean isTv) { 69 mContext = null; 70 mIsTv = isTv; 71 mIsTablet = false; 72 } 73 74 /** Returns a drawable for an icon representing the given audioDeviceType. */ getIconFromAudioDeviceType(@udioDeviceType int audioDeviceType)75 public Drawable getIconFromAudioDeviceType(@AudioDeviceType int audioDeviceType) { 76 return mContext.getDrawable(getIconResIdFromAudioDeviceType(audioDeviceType)); 77 } 78 79 /** Returns a drawable res ID for an icon representing the given audioDeviceType. */ 80 @DrawableRes getIconResIdFromAudioDeviceType(@udioDeviceType int audioDeviceType)81 public int getIconResIdFromAudioDeviceType(@AudioDeviceType int audioDeviceType) { 82 int mediaRouteType = 83 AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.get(audioDeviceType, /* defaultValue */ -1); 84 return getIconResIdFromMediaRouteType(mediaRouteType); 85 } 86 87 /** Returns a drawable res ID for an icon representing the given mediaRouteType. */ 88 @DrawableRes getIconResIdFromMediaRouteType(@ediaRoute2Info.Type int type)89 public int getIconResIdFromMediaRouteType(@MediaRoute2Info.Type int type) { 90 return mIsTv 91 ? getIconResourceIdForTv(type) 92 : getIconResourceIdForPhoneOrTablet(type, mIsTablet); 93 } 94 95 @SuppressLint("SwitchIntDef") 96 @DrawableRes getIconResourceIdForPhoneOrTablet( @ediaRoute2Info.Type int type, boolean isTablet)97 private static int getIconResourceIdForPhoneOrTablet( 98 @MediaRoute2Info.Type int type, boolean isTablet) { 99 int defaultResId = isTablet ? R.drawable.ic_media_tablet : R.drawable.ic_smartphone; 100 101 return switch (type) { 102 case MediaRoute2Info.TYPE_USB_DEVICE, 103 MediaRoute2Info.TYPE_USB_HEADSET, 104 MediaRoute2Info.TYPE_USB_ACCESSORY, 105 MediaRoute2Info.TYPE_WIRED_HEADSET, 106 MediaRoute2Info.TYPE_WIRED_HEADPHONES -> 107 R.drawable.ic_headphone; 108 case MediaRoute2Info.TYPE_DOCK -> R.drawable.ic_dock_device; 109 case MediaRoute2Info.TYPE_HDMI, 110 MediaRoute2Info.TYPE_HDMI_ARC, 111 MediaRoute2Info.TYPE_HDMI_EARC -> 112 R.drawable.ic_external_display; 113 default -> defaultResId; // Includes TYPE_BUILTIN_SPEAKER. 114 }; 115 } 116 117 @SuppressLint("SwitchIntDef") 118 @DrawableRes getIconResourceIdForTv(@ediaRoute2Info.Type int type)119 private static int getIconResourceIdForTv(@MediaRoute2Info.Type int type) { 120 return switch (type) { 121 case MediaRoute2Info.TYPE_USB_DEVICE, MediaRoute2Info.TYPE_USB_HEADSET -> 122 R.drawable.ic_headphone; 123 case MediaRoute2Info.TYPE_USB_ACCESSORY -> R.drawable.ic_usb; 124 case MediaRoute2Info.TYPE_DOCK -> R.drawable.ic_dock_device; 125 case MediaRoute2Info.TYPE_HDMI, MediaRoute2Info.TYPE_BUILTIN_SPEAKER -> 126 R.drawable.ic_tv; 127 case MediaRoute2Info.TYPE_HDMI_ARC, MediaRoute2Info.TYPE_HDMI_EARC -> 128 R.drawable.ic_hdmi; 129 case MediaRoute2Info.TYPE_WIRED_HEADSET, MediaRoute2Info.TYPE_WIRED_HEADPHONES -> 130 R.drawable.ic_wired_device; 131 default -> R.drawable.ic_media_speaker_device; 132 }; 133 } 134 135 static { 136 AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_USB_DEVICE, MediaRoute2Info.TYPE_USB_DEVICE); 137 AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_USB_HEADSET, MediaRoute2Info.TYPE_USB_HEADSET); 138 AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put( 139 TYPE_USB_ACCESSORY, MediaRoute2Info.TYPE_USB_ACCESSORY); 140 AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_DOCK, MediaRoute2Info.TYPE_DOCK); 141 AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_HDMI, MediaRoute2Info.TYPE_HDMI); 142 AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_HDMI_ARC, MediaRoute2Info.TYPE_HDMI_ARC); 143 AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_HDMI_EARC, MediaRoute2Info.TYPE_HDMI_EARC); 144 AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put( 145 TYPE_WIRED_HEADSET, MediaRoute2Info.TYPE_WIRED_HEADSET); 146 AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put( 147 TYPE_WIRED_HEADPHONES, MediaRoute2Info.TYPE_WIRED_HEADPHONES); 148 AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put( 149 TYPE_BUILTIN_SPEAKER, MediaRoute2Info.TYPE_BUILTIN_SPEAKER); 150 } 151 } 152