1<?xml version="1.0" encoding="utf-8"?> 2<!-- 3 ~ Copyright (C) 2021 The Android Open Source Project 4 ~ 5 ~ Licensed under the Apache License, Version 2.0 (the "License"); 6 ~ you may not use this file except in compliance with the License. 7 ~ You may obtain a copy of the License at 8 ~ 9 ~ http://www.apache.org/licenses/LICENSE-2.0 10 ~ 11 ~ Unless required by applicable law or agreed to in writing, software 12 ~ distributed under the License is distributed on an "AS IS" BASIS, 13 ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ~ See the License for the specific language governing permissions and 15 ~ limitations under the License. 16 --> 17 18<!-- Layout for media session-based controls --> 19<com.android.systemui.util.animation.TransitionLayout xmlns:android="http://schemas.android.com/apk/res/android" 20 xmlns:app="http://schemas.android.com/apk/res-auto" 21 android:id="@+id/qs_media_controls" 22 android:layout_width="match_parent" 23 android:layout_height="wrap_content" 24 android:clipChildren="true" 25 android:clipToPadding="true" 26 android:gravity="center_horizontal|fill_vertical" 27 android:forceHasOverlappingRendering="false" 28 android:background="@drawable/qs_media_outline_layout_bg" 29 android:clipToOutline="true" 30 android:theme="@style/MediaPlayer"> 31 32 <ImageView 33 android:id="@+id/album_art" 34 android:layout_width="match_parent" 35 android:layout_height="@dimen/qs_media_session_height_expanded" 36 app:layout_constraintStart_toStartOf="parent" 37 app:layout_constraintEnd_toEndOf="parent" 38 app:layout_constraintBottom_toBottomOf="parent" 39 android:translationZ="0dp" 40 android:scaleType="centerCrop" 41 android:adjustViewBounds="true" 42 android:clipToOutline="true" 43 android:background="@drawable/qs_media_outline_album_bg" 44 /> 45 46 <com.android.systemui.surfaceeffects.ripple.MultiRippleView 47 android:id="@+id/touch_ripple_view" 48 android:layout_width="match_parent" 49 android:layout_height="@dimen/qs_media_session_height_expanded" 50 app:layout_constraintStart_toStartOf="@id/album_art" 51 app:layout_constraintEnd_toEndOf="@id/album_art" 52 app:layout_constraintTop_toTopOf="@id/album_art" 53 app:layout_constraintBottom_toBottomOf="@id/album_art" /> 54 55 <com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView 56 android:id="@+id/turbulence_noise_view" 57 android:layout_width="match_parent" 58 android:layout_height="@dimen/qs_media_session_height_expanded" 59 app:layout_constraintStart_toStartOf="@id/album_art" 60 app:layout_constraintEnd_toEndOf="@id/album_art" 61 app:layout_constraintTop_toTopOf="@id/album_art" 62 app:layout_constraintBottom_toBottomOf="@id/album_art" /> 63 64 <!-- Guideline for output switcher --> 65 <androidx.constraintlayout.widget.Guideline 66 android:id="@+id/center_vertical_guideline" 67 android:layout_width="wrap_content" 68 android:layout_height="wrap_content" 69 android:orientation="vertical" 70 app:layout_constraintGuide_percent="0.6" /> 71 72 <!-- Guideline for action buttons (collapsed view only) --> 73 <androidx.constraintlayout.widget.Guideline 74 android:id="@+id/action_button_guideline" 75 android:layout_width="0dp" 76 android:layout_height="0dp" 77 android:orientation="vertical" 78 app:layout_constraintGuide_end="@dimen/qs_media_session_collapsed_guideline" /> 79 80 <!-- App icon --> 81 <com.android.internal.widget.CachingIconView 82 android:id="@+id/icon" 83 android:layout_width="@dimen/qs_media_app_icon_size" 84 android:layout_height="@dimen/qs_media_app_icon_size" 85 android:layout_marginStart="@dimen/qs_media_padding" 86 android:layout_marginTop="@dimen/qs_media_padding" 87 app:layout_constraintStart_toStartOf="parent" 88 app:layout_constraintTop_toTopOf="parent" /> 89 90 <!-- Seamless Output Switcher --> 91 <LinearLayout 92 android:id="@+id/media_seamless" 93 android:orientation="horizontal" 94 android:gravity="top|end" 95 android:paddingTop="@dimen/qs_media_padding" 96 android:paddingEnd="@dimen/qs_media_padding" 97 android:background="@drawable/qs_media_light_source" 98 android:forceHasOverlappingRendering="false" 99 android:layout_width="wrap_content" 100 android:minHeight="@dimen/min_clickable_item_size" 101 android:layout_height="wrap_content" 102 android:layout_marginStart="@dimen/qs_center_guideline_padding" 103 app:layout_constraintEnd_toEndOf="parent" 104 app:layout_constraintTop_toTopOf="parent" 105 app:layout_constraintStart_toEndOf="@id/center_vertical_guideline" 106 app:layout_constraintHorizontal_bias="1" 107 app:layout_constrainedWidth="true" 108 app:layout_constraintWidth_min="@dimen/min_clickable_item_size" 109 app:layout_constraintHeight_min="@dimen/min_clickable_item_size"> 110 <com.android.systemui.animation.view.LaunchableLinearLayout 111 android:id="@+id/media_seamless_button" 112 android:layout_width="wrap_content" 113 android:layout_height="wrap_content" 114 android:minHeight="@dimen/qs_seamless_height" 115 android:maxHeight="@dimen/min_clickable_item_size" 116 android:theme="@style/MediaPlayer.SolidButton" 117 android:background="@drawable/qs_media_seamless_background" 118 android:orientation="horizontal" 119 android:contentDescription="@string/quick_settings_media_device_label"> 120 <ImageView 121 android:id="@+id/media_seamless_image" 122 android:layout_width="@dimen/qs_seamless_icon_size" 123 android:layout_height="@dimen/qs_seamless_icon_size" 124 android:layout_gravity="center" 125 android:tint="?android:attr/textColorPrimary" 126 android:src="@*android:drawable/ic_media_seamless" /> 127 <TextView 128 android:id="@+id/media_seamless_text" 129 android:layout_width="wrap_content" 130 android:layout_height="wrap_content" 131 android:layout_gravity="center_vertical" 132 android:layout_marginStart="4dp" 133 android:fontFamily="@*android:string/config_headlineFontFamilyMedium" 134 android:singleLine="true" 135 android:text="@*android:string/ext_media_seamless_action" 136 android:textDirection="locale" 137 android:textSize="12sp" 138 android:lineHeight="16sp" /> 139 </com.android.systemui.animation.view.LaunchableLinearLayout> 140 </LinearLayout> 141 142 <!-- Song name --> 143 <TextView 144 android:id="@+id/header_title" 145 android:fontFamily="@*android:string/config_headlineFontFamilyMedium" 146 android:singleLine="true" 147 android:textSize="16sp" 148 android:layout_width="wrap_content" 149 android:layout_height="wrap_content" /> 150 151 <!-- Explicit Indicator --> 152 <com.android.internal.widget.CachingIconView 153 android:id="@+id/media_explicit_indicator" 154 android:layout_width="@dimen/qs_media_explicit_indicator_icon_size" 155 android:layout_height="@dimen/qs_media_explicit_indicator_icon_size" 156 android:src="@drawable/ic_media_explicit_indicator" 157 /> 158 159 <!-- Artist name --> 160 <TextView 161 android:id="@+id/header_artist" 162 android:fontFamily="@*android:string/config_headlineFontFamily" 163 android:singleLine="true" 164 style="@style/MediaPlayer.Subtitle" 165 android:textSize="14sp" 166 android:layout_width="wrap_content" 167 android:layout_height="wrap_content" /> 168 169 <ImageButton 170 android:id="@+id/actionPlayPause" 171 style="@style/MediaPlayer.SessionAction.Primary" 172 android:layout_width="48dp" 173 android:layout_height="48dp" 174 android:layout_marginStart="@dimen/qs_media_padding" 175 android:layout_marginEnd="@dimen/qs_media_padding" /> 176 177 <!-- See comment in media_session_collapsed.xml for how these barriers are used --> 178 <androidx.constraintlayout.widget.Barrier 179 android:id="@+id/media_action_barrier_start" 180 android:layout_width="0dp" 181 android:layout_height="0dp" 182 android:orientation="vertical" 183 app:layout_constraintTop_toBottomOf="@id/header_title" 184 app:layout_constraintBottom_toBottomOf="parent" 185 app:layout_constraintStart_toStartOf="parent" 186 app:barrierDirection="start" 187 app:constraint_referenced_ids="actionPrev,media_scrubbing_elapsed_time,media_progress_bar,actionNext,media_scrubbing_total_time,action0,action1,action2,action3,action4" 188 /> 189 <androidx.constraintlayout.widget.Barrier 190 android:id="@+id/media_action_barrier_end" 191 android:layout_width="0dp" 192 android:layout_height="0dp" 193 android:orientation="vertical" 194 app:layout_constraintTop_toBottomOf="@id/media_seamless" 195 app:layout_constraintBottom_toBottomOf="parent" 196 app:barrierDirection="end" 197 app:constraint_referenced_ids="actionPrev,media_scrubbing_elapsed_time,media_progress_bar,actionNext,media_scrubbing_total_time,action0,action1,action2,action3,action4" 198 app:layout_constraintRight_toRightOf="@id/actionPlayPause" 199 /> 200 201 <!-- This barrier is used in expanded view to constrain the bottom row of actions --> 202 <androidx.constraintlayout.widget.Barrier 203 android:id="@+id/media_action_barrier_top" 204 android:layout_width="match_parent" 205 android:layout_height="0dp" 206 app:layout_constraintBottom_toBottomOf="parent" 207 app:barrierDirection="top" 208 app:constraint_referenced_ids="actionPrev,media_scrubbing_elapsed_time,media_progress_bar,actionNext,media_scrubbing_total_time,action0,action1,action2,action3,action4" 209 /> 210 211 <!-- Button visibility will be controlled in code --> 212 <ImageButton 213 android:id="@+id/actionPrev" 214 style="@style/MediaPlayer.SessionAction.Secondary" 215 android:layout_width="48dp" 216 android:layout_height="48dp" 217 android:layout_marginStart="4dp" 218 android:layout_marginEnd="0dp" 219 android:layout_marginBottom="@dimen/qs_media_padding" 220 android:layout_marginTop="0dp" 221 /> 222 223 <!-- Elapsed time, shown only when scrubbing --> 224 <!-- The space to the left of the progress bar will either be actionPrev or 225 media_scrubbing_elapsed_time, so they use the same layout constraints. Visibilities of 226 elements are controlled in code. --> 227 <TextView 228 android:id="@+id/media_scrubbing_elapsed_time" 229 style="@style/MediaPlayer.ScrubbingTime" 230 android:layout_width="48dp" 231 android:layout_height="48dp" 232 android:layout_marginStart="4dp" 233 android:layout_marginEnd="0dp" 234 android:layout_marginBottom="@dimen/qs_media_padding" 235 android:layout_marginTop="0dp" 236 android:visibility="gone" 237 /> 238 239 <!-- Seek Bar --> 240 <!-- As per Material Design on Bidirectionality, this is forced to LTR in code --> 241 <SeekBar 242 android:id="@+id/media_progress_bar" 243 style="@style/MediaPlayer.ProgressBar" 244 android:layout_width="0dp" 245 android:layout_height="48dp" 246 android:paddingTop="@dimen/qs_media_session_enabled_seekbar_vertical_padding" 247 android:paddingBottom="12dp" 248 android:maxHeight="@dimen/qs_media_enabled_seekbar_height" 249 android:splitTrack="false" 250 android:layout_marginBottom="@dimen/qs_media_padding" 251 android:layout_marginTop="0dp" 252 android:layout_marginStart="0dp" 253 android:layout_marginEnd="0dp" /> 254 255 <ImageButton 256 android:id="@+id/actionNext" 257 style="@style/MediaPlayer.SessionAction.Secondary" 258 android:layout_width="48dp" 259 android:layout_height="48dp" 260 android:layout_marginStart="0dp" 261 android:layout_marginEnd="@dimen/qs_media_action_spacing" 262 android:layout_marginBottom="@dimen/qs_media_padding" 263 android:layout_marginTop="0dp" /> 264 265 <!-- Total time, shown only when scrubbing --> 266 <!-- The space to the right of the progress bar will either be actionNext or 267 media_scrubbing_total_time, so they use the same layout constraints. Visibilities of 268 elements are controlled in code. --> 269 <TextView 270 android:id="@+id/media_scrubbing_total_time" 271 style="@style/MediaPlayer.ScrubbingTime" 272 android:layout_width="48dp" 273 android:layout_height="48dp" 274 android:layout_marginStart="0dp" 275 android:layout_marginEnd="@dimen/qs_media_action_spacing" 276 android:layout_marginBottom="@dimen/qs_media_padding" 277 android:layout_marginTop="0dp" 278 android:visibility="gone" 279 /> 280 281 <ImageButton 282 android:id="@+id/action0" 283 style="@style/MediaPlayer.SessionAction.Secondary" 284 android:layout_width="48dp" 285 android:layout_height="48dp" 286 android:layout_marginStart="@dimen/qs_media_action_spacing" 287 android:layout_marginEnd="@dimen/qs_media_action_spacing" 288 android:layout_marginBottom="@dimen/qs_media_padding" 289 android:layout_marginTop="0dp"/> 290 291 <ImageButton 292 android:id="@+id/action1" 293 style="@style/MediaPlayer.SessionAction.Secondary" 294 android:layout_width="48dp" 295 android:layout_height="48dp" 296 android:layout_marginStart="@dimen/qs_media_action_spacing" 297 android:layout_marginEnd="4dp" 298 android:layout_marginBottom="@dimen/qs_media_padding" 299 android:layout_marginTop="0dp" /> 300 301 <ImageButton 302 android:id="@+id/action2" 303 style="@style/MediaPlayer.SessionAction.Secondary" 304 android:layout_width="48dp" 305 android:layout_height="48dp" 306 android:layout_marginStart="@dimen/qs_media_action_spacing" 307 android:layout_marginEnd="4dp" 308 android:layout_marginBottom="@dimen/qs_media_padding" 309 android:layout_marginTop="0dp" /> 310 311 <ImageButton 312 android:id="@+id/action3" 313 style="@style/MediaPlayer.SessionAction.Secondary" 314 android:layout_width="48dp" 315 android:layout_height="48dp" 316 android:layout_marginStart="@dimen/qs_media_action_spacing" 317 android:layout_marginEnd="4dp" 318 android:layout_marginBottom="@dimen/qs_media_padding" 319 android:layout_marginTop="0dp" /> 320 321 <ImageButton 322 android:id="@+id/action4" 323 style="@style/MediaPlayer.SessionAction.Secondary" 324 android:layout_width="48dp" 325 android:layout_height="48dp" 326 android:layout_marginStart="@dimen/qs_media_action_spacing" 327 android:layout_marginEnd="4dp" 328 android:layout_marginBottom="@dimen/qs_media_padding" 329 android:layout_marginTop="0dp" /> 330 331 <include 332 layout="@layout/media_long_press_menu" /> 333 334</com.android.systemui.util.animation.TransitionLayout> 335