Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9e74f5f authored by Beth Thibodeau's avatar Beth Thibodeau
Browse files

Add fallback media layout for notification actions

Adds more button slots which are dynamically shown depending on which actions
are supported for the app's media.

When PlaybackState actions are available, the large play/pause button
will appear, along with prev/next on either side of the progress bar.
When Notification actions are used, those buttons will be hidden and up
to 5 actions will be shown to the right of the progress bar instead.

Also refactored view holder classes and test since both templates have 5
generic action buttons now.

Fixes: 218875984
Bug: 218876469
Test: atest MediaControlPanelTest
Change-Id: I464834d2eee53d661f2407f6280e2856c96c63ac
parent 71437d58
Loading
Loading
Loading
Loading
+77 −32
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
        android:background="@drawable/qs_media_scrim"
        />

    <!-- Guideline for output switcher -->
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/center_vertical_guideline"
        android:layout_width="wrap_content"
@@ -51,6 +52,14 @@
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.6" />

    <!-- Guideline for action buttons (collapsed view only) -->
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/action_button_guideline"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintGuide_end="@dimen/qs_media_session_collapsed_guideline" />

    <!-- App icon -->
    <com.android.internal.widget.CachingIconView
        android:id="@+id/icon"
@@ -118,15 +127,7 @@
        android:singleLine="true"
        android:textSize="16sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginStart="@dimen/qs_media_padding"
        android:layout_marginEnd="@dimen/qs_media_padding"
        app:layout_constrainedWidth="true"
        app:layout_constraintTop_toBottomOf="@id/icon"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
        app:layout_constraintHorizontal_bias="0" />
        android:layout_height="wrap_content" />

    <!-- Artist name -->
    <TextView
@@ -136,15 +137,7 @@
        style="@style/MediaPlayer.Subtitle"
        android:textSize="14sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="@dimen/qs_media_padding"
        app:layout_constrainedWidth="true"
        android:layout_marginTop="0dp"
        app:layout_constraintTop_toBottomOf="@id/header_title"
        app:layout_constraintStart_toStartOf="@id/header_title"
        app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
        app:layout_constraintBottom_toBottomOf="@id/actionPlayPause"
        app:layout_constraintHorizontal_bias="0" />
        android:layout_height="wrap_content" />

    <ImageButton
        android:id="@+id/actionPlayPause"
@@ -153,9 +146,33 @@
        android:layout_height="48dp"
        android:layout_marginStart="@dimen/qs_media_padding"
        android:layout_marginEnd="@dimen/qs_media_padding"
        android:layout_marginTop="0dp"
        android:layout_marginBottom="0dp" />
         />

    <!-- See comment in media_session_collapsed.xml for how these barriers are used -->
    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/media_action_barrier"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintTop_toBottomOf="@id/header_title"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:barrierDirection="start"
        app:constraint_referenced_ids="actionPrev,media_progress_bar,actionNext,action0,action1,action2,action3,action4"
        />
    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/media_action_barrier_end"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintTop_toBottomOf="@id/media_seamless"
        app:layout_constraintBottom_toBottomOf="parent"
        app:barrierDirection="end"
        app:constraint_referenced_ids="actionPrev,media_progress_bar,actionNext,action0,action1,action2,action3,action4"
        app:layout_constraintStart_toStartOf="parent"
        />

    <!-- Button visibility will be controlled in code -->
    <ImageButton
        android:id="@+id/actionPrev"
        style="@style/MediaPlayer.SessionAction"
@@ -163,10 +180,9 @@
        android:layout_height="48dp"
        android:layout_marginStart="4dp"
        android:layout_marginEnd="0dp"
        android:layout_marginBottom="0dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:layout_marginTop="0dp"
        app:layout_constraintHorizontal_bias="1"
        app:layout_constraintHorizontal_chainStyle="packed" />
        />

    <!-- Seek Bar -->
    <!-- As per Material Design on Bidirectionality, this is forced to LTR in code -->
@@ -174,12 +190,12 @@
        android:id="@+id/media_progress_bar"
        style="@style/MediaPlayer.ProgressBar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_height="48dp"
        android:paddingTop="@dimen/qs_media_session_enabled_seekbar_vertical_padding"
        android:paddingBottom="12dp"
        android:maxHeight="@dimen/qs_media_enabled_seekbar_height"
        android:splitTrack="false"
        android:layout_marginBottom="0dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:layout_marginTop="0dp"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp" />
@@ -191,29 +207,58 @@
        android:layout_height="48dp"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="@dimen/qs_media_action_spacing"
        android:layout_marginBottom="0dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:layout_marginTop="0dp" />

    <ImageButton
        android:id="@+id/actionStart"
        android:id="@+id/action0"
        style="@style/MediaPlayer.SessionAction"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginStart="@dimen/qs_media_action_spacing"
        android:layout_marginEnd="@dimen/qs_media_action_spacing"
        android:layout_marginBottom="0dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:layout_marginTop="0dp"/>

    <ImageButton
        android:id="@+id/actionEnd"
        android:id="@+id/action1"
        style="@style/MediaPlayer.SessionAction"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginStart="@dimen/qs_media_action_spacing"
        android:layout_marginEnd="4dp"
        android:layout_marginBottom="0dp"
        android:layout_marginTop="0dp"
        app:layout_constraintHorizontal_chainStyle="packed" />
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:layout_marginTop="0dp" />

    <ImageButton
        android:id="@+id/action2"
        style="@style/MediaPlayer.SessionAction"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginStart="@dimen/qs_media_action_spacing"
        android:layout_marginEnd="4dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:layout_marginTop="0dp" />

    <ImageButton
        android:id="@+id/action3"
        style="@style/MediaPlayer.SessionAction"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginStart="@dimen/qs_media_action_spacing"
        android:layout_marginEnd="4dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:layout_marginTop="0dp" />

    <ImageButton
        android:id="@+id/action4"
        style="@style/MediaPlayer.SessionAction"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginStart="@dimen/qs_media_action_spacing"
        android:layout_marginEnd="4dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:layout_marginTop="0dp" />

    <!-- Long press menu -->
    <TextView
+1 −0
Original line number Diff line number Diff line
@@ -983,6 +983,7 @@
    <dimen name="qs_media_seekbar_progress_amplitude">1.5dp</dimen>
    <dimen name="qs_media_seekbar_progress_phase">8dp</dimen>
    <dimen name="qs_media_seekbar_progress_stroke_width">2dp</dimen>
    <dimen name="qs_media_session_collapsed_guideline">144dp</dimen>

    <!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
    <dimen name="qs_aa_media_rec_album_size_collapsed">72dp</dimen>
+104 −16
Original line number Diff line number Diff line
@@ -18,6 +18,13 @@
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <Constraint
        android:id="@+id/media_action_barrier"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/media_seamless"
        app:layout_constraintStart_toEndOf="@id/action_button_guideline" />

    <Constraint
        android:id="@+id/album_art"
        android:layout_width="match_parent"
@@ -27,34 +34,74 @@
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

    <Constraint
        android:id="@+id/header_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginStart="@dimen/qs_media_padding"
        android:layout_marginEnd="@dimen/qs_media_padding"
        app:layout_constraintEnd_toStartOf="@id/action_button_guideline"
        app:layout_constrainedWidth="true"
        app:layout_constraintTop_toBottomOf="@id/icon"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintHorizontal_bias="0" />
    <Constraint
        android:id="@+id/header_artist"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="@dimen/qs_media_padding"
        android:layout_marginTop="0dp"
        app:layout_constraintEnd_toStartOf="@id/action_button_guideline"
        app:layout_constrainedWidth="true"
        app:layout_constraintTop_toBottomOf="@id/header_title"
        app:layout_constraintStart_toStartOf="@id/header_title"
        app:layout_constraintVertical_bias="0"
        app:layout_constraintHorizontal_bias="0" />

    <Constraint
        android:id="@+id/actionPlayPause"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginEnd="@dimen/qs_media_padding"
        app:layout_constraintStart_toEndOf="@id/actionEnd"
        android:layout_marginBottom="@dimen/qs_media_padding"
        app:layout_constraintVertical_bias="1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/media_seamless"
        app:layout_constraintBottom_toBottomOf="parent" />
        app:layout_constraintStart_toEndOf="@id/media_action_barrier_end" />

    <!--
    There will only be 3 action buttons shown at most in this layout (controlled in code).
    Play/Pause should always be at the end, but the other buttons should remain in the same order
    when in RTL.
    This is accomplished by setting two barriers at the start and end of the small buttons,
    anchored to a guideline set at 3x button width from the end. The text and play/pause button are
    positioned relative to the barriers, and the small buttons use right/left constraints to stay
    in the correct order inside the barriers.
    -->
    <Constraint
        android:id="@+id/actionPrev"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        app:layout_constraintHorizontal_bias="1"
        app:layout_constraintVertical_bias="1"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toEndOf="@id/header_artist"
        app:layout_constraintEnd_toStartOf="@id/media_progress_bar"
        app:layout_constraintRight_toLeftOf="@id/media_progress_bar"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/media_seamless" />
        app:layout_constraintTop_toBottomOf="@id/media_seamless"
        app:layout_constraintLeft_toRightOf="@id/media_action_barrier" />

    <Constraint
        android:id="@+id/media_progress_bar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:visibility="gone"
        app:layout_constraintStart_toEndOf="@id/actionPrev"
        app:layout_constraintEnd_toStartOf="@id/actionNext"
        app:layout_constraintVertical_bias="1"
        app:layout_constraintLeft_toRightOf="@id/actionPrev"
        app:layout_constraintRight_toLeftOf="@id/actionNext"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/media_seamless" />

@@ -62,29 +109,70 @@
        android:id="@+id/actionNext"
        android:layout_width="48dp"
        android:layout_height="48dp"
        app:layout_constraintStart_toEndOf="@id/media_progress_bar"
        app:layout_constraintEnd_toStartOf="@id/actionStart"
        android:layout_marginBottom="@dimen/qs_media_padding"
        app:layout_constraintVertical_bias="1"
        app:layout_constraintLeft_toRightOf="@id/media_progress_bar"
        app:layout_constraintRight_toLeftOf="@id/action0"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/media_seamless" />

    <Constraint
        android:id="@+id/action0"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:visibility="gone"
        app:layout_constraintVertical_bias="1"
        app:layout_constraintLeft_toRightOf="@id/actionNext"
        app:layout_constraintRight_toLeftOf="@id/action1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/media_seamless" />

    <Constraint
        android:id="@+id/actionStart"
        android:id="@+id/action1"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:visibility="gone"
        app:layout_constraintStart_toEndOf="@id/actionNext"
        app:layout_constraintEnd_toStartOf="@id/actionEnd"
        app:layout_constraintVertical_bias="1"
        app:layout_constraintLeft_toRightOf="@id/action0"
        app:layout_constraintRight_toLeftOf="@id/action2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/media_seamless" />

    <Constraint
        android:id="@+id/actionEnd"
        android:id="@+id/action2"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:visibility="gone"
        app:layout_constraintStart_toEndOf="@id/actionStart"
        app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
        app:layout_constraintVertical_bias="1"
        app:layout_constraintLeft_toRightOf="@id/action1"
        app:layout_constraintRight_toLeftOf="@id/action3"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/media_seamless" />

    <Constraint
        android:id="@+id/action3"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:visibility="gone"
        app:layout_constraintVertical_bias="1"
        app:layout_constraintLeft_toRightOf="@id/action2"
        app:layout_constraintRight_toLeftOf="@id/action4"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/media_seamless" />

    <Constraint
        android:id="@+id/action4"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:visibility="gone"
        app:layout_constraintVertical_bias="1"
        app:layout_constraintLeft_toRightOf="@id/action3"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/media_seamless"
        app:layout_constraintRight_toLeftOf="@id/media_action_barrier_end" />
</ConstraintSet>
+81 −20
Original line number Diff line number Diff line
@@ -27,58 +27,119 @@
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

    <Constraint
        android:id="@+id/header_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginStart="@dimen/qs_media_padding"
        android:layout_marginEnd="@dimen/qs_media_padding"
        app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
        app:layout_constrainedWidth="true"
        app:layout_constraintTop_toBottomOf="@id/icon"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintHorizontal_bias="0" />
    <Constraint
        android:id="@+id/header_artist"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="@dimen/qs_media_padding"
        android:layout_marginTop="0dp"
        app:layout_constrainedWidth="true"
        app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
        app:layout_constraintBottom_toTopOf="@id/media_action_barrier"
        app:layout_constraintTop_toBottomOf="@id/header_title"
        app:layout_constraintStart_toStartOf="@id/header_title"
        app:layout_constraintVertical_bias="0"
        app:layout_constraintHorizontal_bias="0" />

    <Constraint
        android:id="@+id/actionPlayPause"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginStart="@dimen/qs_media_padding"
        android:layout_marginEnd="@dimen/qs_media_padding"
        android:layout_marginBottom="0dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/media_seamless"
        app:layout_constraintBottom_toTopOf="@id/actionEnd" />
        app:layout_constraintBottom_toBottomOf="@id/header_artist" />

    <!--
    The bottom row of action buttons should remain in the same order when RTL, so their constraints
    are set with right/left instead of start/end.
    The chain is set to "spread" so that the progress bar can be weighted to fill any empty space.
     -->
    <Constraint
        android:id="@+id/actionPrev"
        android:layout_width="48dp"
        android:layout_height="48dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/media_progress_bar"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/media_progress_bar"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/actionPlayPause" />
        app:layout_constraintTop_toBottomOf="@id/header_artist"
        app:layout_constraintHorizontal_chainStyle="spread" />

    <Constraint
        android:id="@+id/media_progress_bar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toEndOf="@id/actionPrev"
        app:layout_constraintEnd_toStartOf="@id/actionNext"
        android:layout_height="48dp"
        app:layout_constraintLeft_toRightOf="@id/actionPrev"
        app:layout_constraintRight_toLeftOf="@id/actionNext"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/actionPlayPause" />
        app:layout_constraintTop_toBottomOf="@id/header_artist"
        app:layout_constraintHorizontal_weight="1" />

    <Constraint
        android:id="@+id/actionNext"
        android:layout_width="48dp"
        android:layout_height="48dp"
        app:layout_constraintStart_toEndOf="@id/media_progress_bar"
        app:layout_constraintEnd_toStartOf="@id/actionStart"
        app:layout_constraintLeft_toRightOf="@id/media_progress_bar"
        app:layout_constraintRight_toLeftOf="@id/action0"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/actionPlayPause" />
        app:layout_constraintTop_toBottomOf="@id/header_artist" />

    <Constraint
        android:id="@+id/actionStart"
        android:id="@+id/action0"
        android:layout_width="48dp"
        android:layout_height="48dp"
        app:layout_constraintStart_toEndOf="@id/actionNext"
        app:layout_constraintEnd_toStartOf="@id/actionEnd"
        app:layout_constraintLeft_toRightOf="@id/actionNext"
        app:layout_constraintRight_toLeftOf="@id/action1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/actionPlayPause" />
        app:layout_constraintTop_toBottomOf="@id/header_artist" />

    <Constraint
        android:id="@+id/actionEnd"
        android:id="@+id/action1"
        android:layout_width="48dp"
        android:layout_height="48dp"
        app:layout_constraintStart_toEndOf="@id/actionStart"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintLeft_toRightOf="@id/action0"
        app:layout_constraintRight_toLeftOf="@id/action2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/actionPlayPause" />
        app:layout_constraintTop_toBottomOf="@id/header_artist" />

    <Constraint
        android:id="@+id/action2"
        android:layout_width="48dp"
        android:layout_height="48dp"
        app:layout_constraintLeft_toRightOf="@id/action1"
        app:layout_constraintRight_toLeftOf="@id/action3"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/header_artist" />

    <Constraint
        android:id="@+id/action3"
        android:layout_width="48dp"
        android:layout_height="48dp"
        app:layout_constraintLeft_toRightOf="@id/action2"
        app:layout_constraintRight_toLeftOf="@id/action4"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/header_artist" />

    <Constraint
        android:id="@+id/action4"
        android:layout_width="48dp"
        android:layout_height="48dp"
        app:layout_constraintLeft_toRightOf="@id/action3"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/header_artist" />
</ConstraintSet>
+68 −12

File changed.

Preview size limit exceeded, changes collapsed.

Loading