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 android:clipToOutline="true" 55 android:background="@drawable/qs_media_outline_layout_bg" 56 /> 57 58 <com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView 59 android:id="@+id/turbulence_noise_view" 60 android:layout_width="match_parent" 61 android:layout_height="@dimen/qs_media_session_height_expanded" 62 app:layout_constraintStart_toStartOf="@id/album_art" 63 app:layout_constraintEnd_toEndOf="@id/album_art" 64 app:layout_constraintTop_toTopOf="@id/album_art" 65 app:layout_constraintBottom_toBottomOf="@id/album_art" 66 android:clipToOutline="true" 67 android:background="@drawable/qs_media_outline_layout_bg" 68 /> 69 70 <com.android.systemui.surfaceeffects.loadingeffect.LoadingEffectView 71 android:id="@+id/loading_effect_view" 72 android:layout_width="match_parent" 73 android:layout_height="@dimen/qs_media_session_height_expanded" 74 app:layout_constraintStart_toStartOf="@id/album_art" 75 app:layout_constraintEnd_toEndOf="@id/album_art" 76 app:layout_constraintTop_toTopOf="@id/album_art" 77 app:layout_constraintBottom_toBottomOf="@id/album_art" 78 android:clipToOutline="true" 79 android:background="@drawable/qs_media_outline_layout_bg" 80 /> 81 82 <!-- Guideline for output switcher --> 83 <androidx.constraintlayout.widget.Guideline 84 android:id="@+id/center_vertical_guideline" 85 android:layout_width="wrap_content" 86 android:layout_height="wrap_content" 87 android:orientation="vertical" 88 app:layout_constraintGuide_percent="0.6" /> 89 90 <!-- Guideline for action buttons (collapsed view only) --> 91 <androidx.constraintlayout.widget.Guideline 92 android:id="@+id/action_button_guideline" 93 android:layout_width="0dp" 94 android:layout_height="0dp" 95 android:orientation="vertical" 96 app:layout_constraintGuide_end="@dimen/qs_media_session_collapsed_guideline" /> 97 98 <!-- App icon --> 99 <com.android.internal.widget.CachingIconView 100 android:id="@+id/icon" 101 android:layout_width="@dimen/qs_media_app_icon_size" 102 android:layout_height="@dimen/qs_media_app_icon_size" 103 android:layout_marginStart="@dimen/qs_media_padding" 104 android:layout_marginTop="@dimen/qs_media_padding" 105 app:layout_constraintStart_toStartOf="parent" 106 app:layout_constraintTop_toTopOf="parent" /> 107 108 <!-- Seamless Output Switcher --> 109 <LinearLayout 110 android:id="@+id/media_seamless" 111 android:orientation="horizontal" 112 android:gravity="top|end" 113 android:paddingTop="@dimen/qs_media_padding" 114 android:paddingEnd="@dimen/qs_media_padding" 115 android:background="@drawable/qs_media_light_source" 116 android:forceHasOverlappingRendering="false" 117 android:layout_width="wrap_content" 118 android:minHeight="@dimen/min_clickable_item_size" 119 android:layout_height="wrap_content" 120 android:layout_marginStart="@dimen/qs_center_guideline_padding" 121 app:layout_constraintEnd_toEndOf="parent" 122 app:layout_constraintTop_toTopOf="parent" 123 app:layout_constraintStart_toEndOf="@id/center_vertical_guideline" 124 app:layout_constraintHorizontal_bias="1" 125 app:layout_constrainedWidth="true" 126 app:layout_constraintWidth_min="@dimen/min_clickable_item_size" 127 app:layout_constraintHeight_min="@dimen/min_clickable_item_size"> 128 <com.android.systemui.animation.view.LaunchableLinearLayout 129 android:id="@+id/media_seamless_button" 130 android:layout_width="wrap_content" 131 android:layout_height="wrap_content" 132 android:minHeight="@dimen/qs_seamless_height" 133 android:maxHeight="@dimen/min_clickable_item_size" 134 android:theme="@style/MediaPlayer.SolidButton" 135 android:background="@drawable/qs_media_seamless_background" 136 android:orientation="horizontal" 137 android:contentDescription="@string/quick_settings_media_device_label"> 138 <ImageView 139 android:id="@+id/media_seamless_image" 140 android:layout_width="@dimen/qs_seamless_icon_size" 141 android:layout_height="@dimen/qs_seamless_icon_size" 142 android:layout_gravity="center" 143 android:tint="?android:attr/textColorPrimary" 144 android:src="@*android:drawable/ic_media_seamless" /> 145 <TextView 146 android:id="@+id/media_seamless_text" 147 android:layout_width="wrap_content" 148 android:layout_height="wrap_content" 149 android:layout_gravity="center_vertical" 150 android:layout_marginStart="4dp" 151 android:fontFamily="@*android:string/config_headlineFontFamilyMedium" 152 android:singleLine="true" 153 android:text="@*android:string/ext_media_seamless_action" 154 android:textDirection="locale" 155 android:textSize="12sp" 156 android:lineHeight="16sp" /> 157 </com.android.systemui.animation.view.LaunchableLinearLayout> 158 </LinearLayout> 159 160 <!-- Song name --> 161 <TextView 162 android:id="@+id/header_title" 163 android:fontFamily="@*android:string/config_headlineFontFamilyMedium" 164 android:singleLine="true" 165 android:textSize="16sp" 166 android:layout_width="wrap_content" 167 android:layout_height="wrap_content" /> 168 169 <!-- Explicit Indicator --> 170 <com.android.internal.widget.CachingIconView 171 android:id="@+id/media_explicit_indicator" 172 android:layout_width="@dimen/qs_media_explicit_indicator_icon_size" 173 android:layout_height="@dimen/qs_media_explicit_indicator_icon_size" 174 android:src="@drawable/ic_media_explicit_indicator" 175 /> 176 177 <!-- Artist name --> 178 <TextView 179 android:id="@+id/header_artist" 180 android:fontFamily="@*android:string/config_headlineFontFamily" 181 android:singleLine="true" 182 style="@style/MediaPlayer.Subtitle" 183 android:textSize="14sp" 184 android:layout_width="wrap_content" 185 android:layout_height="wrap_content" /> 186 187 <ImageButton 188 android:id="@+id/actionPlayPause" 189 style="@style/MediaPlayer.SessionAction.Primary" 190 android:layout_width="48dp" 191 android:layout_height="48dp" 192 android:layout_marginStart="@dimen/qs_media_padding" 193 android:layout_marginEnd="@dimen/qs_media_padding" /> 194 195 <!-- See comment in media_session_collapsed.xml for how these barriers are used --> 196 <androidx.constraintlayout.widget.Barrier 197 android:id="@+id/media_action_barrier_start" 198 android:layout_width="0dp" 199 android:layout_height="0dp" 200 android:orientation="vertical" 201 app:layout_constraintTop_toBottomOf="@id/header_title" 202 app:layout_constraintBottom_toBottomOf="parent" 203 app:layout_constraintStart_toStartOf="parent" 204 app:barrierDirection="start" 205 app:constraint_referenced_ids="actionPrev,media_scrubbing_elapsed_time,media_progress_bar,actionNext,media_scrubbing_total_time,action0,action1,action2,action3,action4" 206 /> 207 <androidx.constraintlayout.widget.Barrier 208 android:id="@+id/media_action_barrier_end" 209 android:layout_width="0dp" 210 android:layout_height="0dp" 211 android:orientation="vertical" 212 app:layout_constraintTop_toBottomOf="@id/media_seamless" 213 app:layout_constraintBottom_toBottomOf="parent" 214 app:barrierDirection="end" 215 app:constraint_referenced_ids="actionPrev,media_scrubbing_elapsed_time,media_progress_bar,actionNext,media_scrubbing_total_time,action0,action1,action2,action3,action4" 216 app:layout_constraintRight_toRightOf="@id/actionPlayPause" 217 /> 218 219 <!-- This barrier is used in expanded view to constrain the bottom row of actions --> 220 <androidx.constraintlayout.widget.Barrier 221 android:id="@+id/media_action_barrier_top" 222 android:layout_width="match_parent" 223 android:layout_height="0dp" 224 app:layout_constraintBottom_toBottomOf="parent" 225 app:barrierDirection="top" 226 app:constraint_referenced_ids="actionPrev,media_scrubbing_elapsed_time,media_progress_bar,actionNext,media_scrubbing_total_time,action0,action1,action2,action3,action4" 227 /> 228 229 <!-- Button visibility will be controlled in code --> 230 <ImageButton 231 android:id="@+id/actionPrev" 232 style="@style/MediaPlayer.SessionAction.Secondary" 233 android:layout_width="48dp" 234 android:layout_height="48dp" 235 android:layout_marginStart="4dp" 236 android:layout_marginEnd="0dp" 237 android:layout_marginBottom="@dimen/qs_media_padding" 238 android:layout_marginTop="0dp" 239 /> 240 241 <!-- Elapsed time, shown only when scrubbing --> 242 <!-- The space to the left of the progress bar will either be actionPrev or 243 media_scrubbing_elapsed_time, so they use the same layout constraints. Visibilities of 244 elements are controlled in code. --> 245 <TextView 246 android:id="@+id/media_scrubbing_elapsed_time" 247 style="@style/MediaPlayer.ScrubbingTime" 248 android:layout_width="48dp" 249 android:layout_height="48dp" 250 android:layout_marginStart="4dp" 251 android:layout_marginEnd="0dp" 252 android:layout_marginBottom="@dimen/qs_media_padding" 253 android:layout_marginTop="0dp" 254 android:visibility="gone" 255 /> 256 257 <!-- Seek Bar --> 258 <!-- As per Material Design on Bidirectionality, this is forced to LTR in code --> 259 <SeekBar 260 android:id="@+id/media_progress_bar" 261 style="@style/MediaPlayer.ProgressBar" 262 android:layout_width="0dp" 263 android:layout_height="48dp" 264 android:paddingTop="@dimen/qs_media_session_enabled_seekbar_vertical_padding" 265 android:paddingBottom="12dp" 266 android:maxHeight="@dimen/qs_media_enabled_seekbar_height" 267 android:splitTrack="false" 268 android:layout_marginBottom="@dimen/qs_media_padding" 269 android:layout_marginTop="0dp" 270 android:layout_marginStart="0dp" 271 android:layout_marginEnd="0dp" /> 272 273 <ImageButton 274 android:id="@+id/actionNext" 275 style="@style/MediaPlayer.SessionAction.Secondary" 276 android:layout_width="48dp" 277 android:layout_height="48dp" 278 android:layout_marginStart="0dp" 279 android:layout_marginEnd="@dimen/qs_media_action_spacing" 280 android:layout_marginBottom="@dimen/qs_media_padding" 281 android:layout_marginTop="0dp" /> 282 283 <!-- Total time, shown only when scrubbing --> 284 <!-- The space to the right of the progress bar will either be actionNext or 285 media_scrubbing_total_time, so they use the same layout constraints. Visibilities of 286 elements are controlled in code. --> 287 <TextView 288 android:id="@+id/media_scrubbing_total_time" 289 style="@style/MediaPlayer.ScrubbingTime" 290 android:layout_width="48dp" 291 android:layout_height="48dp" 292 android:layout_marginStart="0dp" 293 android:layout_marginEnd="@dimen/qs_media_action_spacing" 294 android:layout_marginBottom="@dimen/qs_media_padding" 295 android:layout_marginTop="0dp" 296 android:visibility="gone" 297 /> 298 299 <ImageButton 300 android:id="@+id/action0" 301 style="@style/MediaPlayer.SessionAction.Secondary" 302 android:layout_width="48dp" 303 android:layout_height="48dp" 304 android:layout_marginStart="@dimen/qs_media_action_spacing" 305 android:layout_marginEnd="@dimen/qs_media_action_spacing" 306 android:layout_marginBottom="@dimen/qs_media_padding" 307 android:layout_marginTop="0dp"/> 308 309 <ImageButton 310 android:id="@+id/action1" 311 style="@style/MediaPlayer.SessionAction.Secondary" 312 android:layout_width="48dp" 313 android:layout_height="48dp" 314 android:layout_marginStart="@dimen/qs_media_action_spacing" 315 android:layout_marginEnd="4dp" 316 android:layout_marginBottom="@dimen/qs_media_padding" 317 android:layout_marginTop="0dp" /> 318 319 <ImageButton 320 android:id="@+id/action2" 321 style="@style/MediaPlayer.SessionAction.Secondary" 322 android:layout_width="48dp" 323 android:layout_height="48dp" 324 android:layout_marginStart="@dimen/qs_media_action_spacing" 325 android:layout_marginEnd="4dp" 326 android:layout_marginBottom="@dimen/qs_media_padding" 327 android:layout_marginTop="0dp" /> 328 329 <ImageButton 330 android:id="@+id/action3" 331 style="@style/MediaPlayer.SessionAction.Secondary" 332 android:layout_width="48dp" 333 android:layout_height="48dp" 334 android:layout_marginStart="@dimen/qs_media_action_spacing" 335 android:layout_marginEnd="4dp" 336 android:layout_marginBottom="@dimen/qs_media_padding" 337 android:layout_marginTop="0dp" /> 338 339 <ImageButton 340 android:id="@+id/action4" 341 style="@style/MediaPlayer.SessionAction.Secondary" 342 android:layout_width="48dp" 343 android:layout_height="48dp" 344 android:layout_marginStart="@dimen/qs_media_action_spacing" 345 android:layout_marginEnd="4dp" 346 android:layout_marginBottom="@dimen/qs_media_padding" 347 android:layout_marginTop="0dp" /> 348 349 <include 350 layout="@layout/media_long_press_menu" /> 351 352</com.android.systemui.util.animation.TransitionLayout> 353