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.systemui.media.dialog; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 23 import com.android.settingslib.media.MediaDevice; 24 import com.android.systemui.res.R; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Optional; 29 30 /** 31 * MediaItem represents an item in OutputSwitcher list (could be a MediaDevice, group divider or 32 * connect new device item). 33 */ 34 public class MediaItem { 35 private final Optional<MediaDevice> mMediaDeviceOptional; 36 private final String mTitle; 37 @MediaItemType 38 private final int mMediaItemType; 39 private final boolean mIsFirstDeviceInGroup; 40 private final boolean mIsExpandableDivider; 41 private final boolean mHasTopSeparator; 42 43 @Retention(RetentionPolicy.SOURCE) 44 @IntDef({ 45 MediaItemType.TYPE_DEVICE, 46 MediaItemType.TYPE_GROUP_DIVIDER, 47 MediaItemType.TYPE_PAIR_NEW_DEVICE, 48 MediaItemType.TYPE_DEVICE_GROUP 49 }) 50 public @interface MediaItemType { 51 int TYPE_DEVICE = 0; 52 int TYPE_GROUP_DIVIDER = 1; 53 int TYPE_PAIR_NEW_DEVICE = 2; 54 int TYPE_DEVICE_GROUP = 3; 55 } 56 57 /** 58 * Returns a new {@link MediaItemType#TYPE_DEVICE} {@link MediaItem} with its {@link 59 * #getMediaDevice() media device} set to {@code device} and its title set to {@code device}'s 60 * name. 61 */ createDeviceMediaItem(@onNull MediaDevice device)62 public static MediaItem createDeviceMediaItem(@NonNull MediaDevice device) { 63 return new MediaItem(device, device.getName(), MediaItemType.TYPE_DEVICE, false); 64 } 65 66 /** 67 * Returns a new {@link MediaItemType#TYPE_DEVICE} {@link MediaItem} with its {@link 68 * #getMediaDevice() media device} set to {@code device} and its title set to {@code device}'s 69 * name. 70 */ createDeviceMediaItem( @onNull MediaDevice device, boolean isFirstDeviceInGroup)71 public static MediaItem createDeviceMediaItem( 72 @NonNull MediaDevice device, boolean isFirstDeviceInGroup) { 73 return new MediaItem( 74 device, device.getName(), MediaItemType.TYPE_DEVICE, isFirstDeviceInGroup); 75 } 76 77 /** 78 * Returns a new {@link MediaItemType#TYPE_DEVICE_GROUP} {@link MediaItem}. This items controls 79 * the volume of the group session. 80 */ createDeviceGroupMediaItem()81 public static MediaItem createDeviceGroupMediaItem() { 82 return new MediaItem( 83 /* device */ null, 84 /* title */ null, 85 /* type */ MediaItemType.TYPE_DEVICE_GROUP, 86 /* misFirstDeviceInGroup */ false); 87 } 88 89 /** 90 * Returns a new {@link MediaItemType#TYPE_PAIR_NEW_DEVICE} {@link MediaItem} with both {@link 91 * #getMediaDevice() media device} and title set to {@code null}. 92 */ createPairNewDeviceMediaItem()93 public static MediaItem createPairNewDeviceMediaItem() { 94 return new MediaItem( 95 /* device */ null, 96 /* title */ null, 97 MediaItemType.TYPE_PAIR_NEW_DEVICE, 98 /* mIsFirstDeviceInGroup */ false); 99 } 100 101 /** 102 * Returns a new {@link MediaItemType#TYPE_GROUP_DIVIDER} {@link MediaItem} with the specified 103 * title and a {@code null} {@link #getMediaDevice() media device}. 104 */ createGroupDividerMediaItem(@ullable String title)105 public static MediaItem createGroupDividerMediaItem(@Nullable String title) { 106 return new MediaItem( 107 /* device */ null, 108 title, 109 MediaItemType.TYPE_GROUP_DIVIDER, 110 /* misFirstDeviceInGroup */ false); 111 } 112 113 /** 114 * Returns a new {@link MediaItemType#TYPE_GROUP_DIVIDER} {@link MediaItem} with the specified 115 * title and a {@code null} {@link #getMediaDevice() media device}. This item needs to be 116 * rendered with a separator above it. 117 */ createGroupDividerWithSeparatorMediaItem(@ullable String title)118 public static MediaItem createGroupDividerWithSeparatorMediaItem(@Nullable String title) { 119 return new MediaItem( 120 /* device */ null, 121 title, 122 MediaItemType.TYPE_GROUP_DIVIDER, 123 /* isFirstDeviceInGroup */ false, 124 /* isExpandableDivider */ false, 125 /* hasTopSeparator */ true); 126 } 127 128 /** 129 * Returns a new {@link MediaItemType#TYPE_GROUP_DIVIDER} {@link MediaItem} with the specified 130 * title and a {@code null} {@link #getMediaDevice() media device}. The item serves as a toggle 131 * for expanding/collapsing the group of devices. 132 */ createExpandableGroupDividerMediaItem(@ullable String title)133 public static MediaItem createExpandableGroupDividerMediaItem(@Nullable String title) { 134 return new MediaItem( 135 /* device */ null, 136 title, 137 MediaItemType.TYPE_GROUP_DIVIDER, 138 /* isFirstDeviceInGroup */ false, 139 /* isExpandableDivider */ true, 140 /* hasTopSeparator */ false); 141 } 142 MediaItem( @ullable MediaDevice device, @Nullable String title, @MediaItemType int type, boolean isFirstDeviceInGroup)143 private MediaItem( 144 @Nullable MediaDevice device, 145 @Nullable String title, 146 @MediaItemType int type, 147 boolean isFirstDeviceInGroup) { 148 this(device, title, type, isFirstDeviceInGroup, /* isExpandableDivider */ 149 false, /* hasTopSeparator */ false); 150 } 151 MediaItem( @ullable MediaDevice device, @Nullable String title, @MediaItemType int type, boolean isFirstDeviceInGroup, boolean isExpandableDivider, boolean hasTopSeparator)152 private MediaItem( 153 @Nullable MediaDevice device, 154 @Nullable String title, 155 @MediaItemType int type, 156 boolean isFirstDeviceInGroup, 157 boolean isExpandableDivider, 158 boolean hasTopSeparator) { 159 this.mMediaDeviceOptional = Optional.ofNullable(device); 160 this.mTitle = title; 161 this.mMediaItemType = type; 162 this.mIsFirstDeviceInGroup = isFirstDeviceInGroup; 163 this.mIsExpandableDivider = isExpandableDivider; 164 this.mHasTopSeparator = hasTopSeparator; 165 } 166 getMediaDevice()167 public Optional<MediaDevice> getMediaDevice() { 168 return mMediaDeviceOptional; 169 } 170 171 /** Get layout id based on media item Type. */ getMediaLayoutId(@ediaItemType int mediaItemType)172 public static int getMediaLayoutId(@MediaItemType int mediaItemType) { 173 return switch (mediaItemType) { 174 case MediaItemType.TYPE_DEVICE, MediaItemType.TYPE_PAIR_NEW_DEVICE -> 175 R.layout.media_output_list_item_advanced; 176 default -> R.layout.media_output_list_group_divider; 177 }; 178 } 179 getTitle()180 public String getTitle() { 181 return mTitle; 182 } 183 isMutingExpectedDevice()184 public boolean isMutingExpectedDevice() { 185 return mMediaDeviceOptional.isPresent() 186 && mMediaDeviceOptional.get().isMutingExpectedDevice(); 187 } 188 getMediaItemType()189 public int getMediaItemType() { 190 return mMediaItemType; 191 } 192 isFirstDeviceInGroup()193 public boolean isFirstDeviceInGroup() { 194 return mIsFirstDeviceInGroup; 195 } 196 197 /** Returns whether a group divider has a button that expands group device list */ isExpandableDivider()198 public boolean isExpandableDivider() { 199 return mIsExpandableDivider; 200 } 201 202 /** Returns whether a group divider has a border at the top */ hasTopSeparator()203 public boolean hasTopSeparator() { 204 return mHasTopSeparator; 205 } 206 } 207