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