Merge "[Media Rec] Use the same long press menu for media player and media recommendations." into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
dc593a705d
105
packages/SystemUI/res/layout/media_long_press_menu.xml
Normal file
105
packages/SystemUI/res/layout/media_long_press_menu.xml
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2022 The Android Open Source Project
|
||||||
|
~
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<merge
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="0dp"
|
||||||
|
android:layout_marginStart="@dimen/qs_media_padding"
|
||||||
|
android:layout_marginEnd="@dimen/qs_media_padding"
|
||||||
|
android:id="@+id/remove_text"
|
||||||
|
android:fontFamily="@*android:string/config_headlineFontFamily"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:marqueeRepeatLimit="marquee_forever"
|
||||||
|
android:text="@string/controls_media_close_session"
|
||||||
|
android:gravity="center_horizontal|top"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/settings"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/cancel" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/settings"
|
||||||
|
android:src="@drawable/ic_settings"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:background="@drawable/qs_media_light_source"
|
||||||
|
android:contentDescription="@string/controls_media_settings_button"
|
||||||
|
android:layout_gravity="top"
|
||||||
|
app:layout_constraintWidth_min="@dimen/min_clickable_item_size"
|
||||||
|
app:layout_constraintHeight_min="@dimen/min_clickable_item_size"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
</ImageButton>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/dismiss"
|
||||||
|
android:background="@drawable/qs_media_light_source"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/qs_media_padding"
|
||||||
|
android:layout_marginEnd="@dimen/qs_media_action_spacing"
|
||||||
|
android:layout_marginBottom="@dimen/qs_media_padding"
|
||||||
|
app:layout_constrainedWidth="true"
|
||||||
|
app:layout_constraintWidth_min="@dimen/min_clickable_item_size"
|
||||||
|
app:layout_constraintHeight_min="@dimen/min_clickable_item_size"
|
||||||
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/cancel"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/remove_text">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/dismiss_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center|top"
|
||||||
|
style="@style/MediaPlayer.SolidButton"
|
||||||
|
android:background="@drawable/qs_media_solid_button"
|
||||||
|
android:text="@string/controls_media_dismiss_button" />
|
||||||
|
</FrameLayout>
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/cancel"
|
||||||
|
android:background="@drawable/qs_media_light_source"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/qs_media_action_spacing"
|
||||||
|
android:layout_marginEnd="@dimen/qs_media_padding"
|
||||||
|
android:layout_marginBottom="@dimen/qs_media_padding"
|
||||||
|
app:layout_constrainedWidth="true"
|
||||||
|
app:layout_constraintWidth_min="@dimen/min_clickable_item_size"
|
||||||
|
app:layout_constraintHeight_min="@dimen/min_clickable_item_size"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/dismiss"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/remove_text">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/cancel_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center|top"
|
||||||
|
style="@style/MediaPlayer.OutlineButton"
|
||||||
|
android:text="@string/cancel" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</merge>
|
||||||
@@ -300,87 +300,7 @@
|
|||||||
android:layout_marginBottom="@dimen/qs_media_padding"
|
android:layout_marginBottom="@dimen/qs_media_padding"
|
||||||
android:layout_marginTop="0dp" />
|
android:layout_marginTop="0dp" />
|
||||||
|
|
||||||
<!-- Long press menu -->
|
<include
|
||||||
<TextView
|
layout="@layout/media_long_press_menu" />
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="0dp"
|
|
||||||
android:layout_marginStart="@dimen/qs_media_padding"
|
|
||||||
android:layout_marginEnd="@dimen/qs_media_padding"
|
|
||||||
android:id="@+id/remove_text"
|
|
||||||
android:fontFamily="@*android:string/config_headlineFontFamily"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:marqueeRepeatLimit="marquee_forever"
|
|
||||||
android:text="@string/controls_media_close_session"
|
|
||||||
android:gravity="center_horizontal|top"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/settings"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/cancel" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/settings"
|
|
||||||
android:src="@drawable/ic_settings"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:background="@drawable/qs_media_light_source"
|
|
||||||
android:contentDescription="@string/controls_media_settings_button"
|
|
||||||
android:layout_gravity="top"
|
|
||||||
app:layout_constraintWidth_min="@dimen/min_clickable_item_size"
|
|
||||||
app:layout_constraintHeight_min="@dimen/min_clickable_item_size"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
</ImageButton>
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/dismiss"
|
|
||||||
android:background="@drawable/qs_media_light_source"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/qs_media_padding"
|
|
||||||
android:layout_marginEnd="@dimen/qs_media_action_spacing"
|
|
||||||
android:layout_marginBottom="@dimen/qs_media_padding"
|
|
||||||
app:layout_constrainedWidth="true"
|
|
||||||
app:layout_constraintWidth_min="@dimen/min_clickable_item_size"
|
|
||||||
app:layout_constraintHeight_min="@dimen/min_clickable_item_size"
|
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/cancel"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/remove_text">
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/dismiss_text"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center|top"
|
|
||||||
style="@style/MediaPlayer.SolidButton"
|
|
||||||
android:background="@drawable/qs_media_solid_button"
|
|
||||||
android:text="@string/controls_media_dismiss_button" />
|
|
||||||
</FrameLayout>
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/cancel"
|
|
||||||
android:background="@drawable/qs_media_light_source"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/qs_media_action_spacing"
|
|
||||||
android:layout_marginEnd="@dimen/qs_media_padding"
|
|
||||||
android:layout_marginBottom="@dimen/qs_media_padding"
|
|
||||||
app:layout_constrainedWidth="true"
|
|
||||||
app:layout_constraintWidth_min="@dimen/min_clickable_item_size"
|
|
||||||
app:layout_constraintHeight_min="@dimen/min_clickable_item_size"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/dismiss"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/remove_text">
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/cancel_text"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center|top"
|
|
||||||
style="@style/MediaPlayer.OutlineButton"
|
|
||||||
android:text="@string/cancel" />
|
|
||||||
</FrameLayout>
|
|
||||||
</com.android.systemui.util.animation.TransitionLayout>
|
</com.android.systemui.util.animation.TransitionLayout>
|
||||||
|
|||||||
@@ -167,97 +167,7 @@
|
|||||||
android:layout_marginBottom="@dimen/qs_media_padding"
|
android:layout_marginBottom="@dimen/qs_media_padding"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Long press menu -->
|
<include
|
||||||
<TextView
|
layout="@layout/media_long_press_menu" />
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="@dimen/qs_media_padding"
|
|
||||||
android:layout_marginStart="@dimen/qs_media_padding"
|
|
||||||
android:layout_marginEnd="@dimen/qs_media_padding"
|
|
||||||
android:id="@+id/remove_text"
|
|
||||||
android:fontFamily="@*android:string/config_headlineFontFamily"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:marqueeRepeatLimit="marquee_forever"
|
|
||||||
android:text="@string/controls_media_close_session"
|
|
||||||
android:gravity="center_horizontal|top"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/cancel"/>
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/settings"
|
|
||||||
android:background="@drawable/qs_media_light_source"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/qs_media_padding"
|
|
||||||
android:layout_marginEnd="@dimen/qs_media_action_spacing"
|
|
||||||
android:layout_marginBottom="@dimen/qs_media_padding"
|
|
||||||
app:layout_constrainedWidth="true"
|
|
||||||
app:layout_constraintWidth_min="48dp"
|
|
||||||
app:layout_constraintHeight_min="48dp"
|
|
||||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/cancel"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/remove_text">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/settings_text"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center|bottom"
|
|
||||||
style="@style/MediaPlayer.OutlineButton"
|
|
||||||
android:text="@string/controls_media_settings_button" />
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/cancel"
|
|
||||||
android:background="@drawable/qs_media_light_source"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/qs_media_action_spacing"
|
|
||||||
android:layout_marginEnd="@dimen/qs_media_action_spacing"
|
|
||||||
android:layout_marginBottom="@dimen/qs_media_padding"
|
|
||||||
app:layout_constrainedWidth="true"
|
|
||||||
app:layout_constraintWidth_min="48dp"
|
|
||||||
app:layout_constraintHeight_min="48dp"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/settings"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/dismiss"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/remove_text">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center|bottom"
|
|
||||||
style="@style/MediaPlayer.OutlineButton"
|
|
||||||
android:text="@string/cancel" />
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/dismiss"
|
|
||||||
android:background="@drawable/qs_media_light_source"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/qs_media_action_spacing"
|
|
||||||
android:layout_marginEnd="@dimen/qs_media_padding"
|
|
||||||
android:layout_marginBottom="@dimen/qs_media_padding"
|
|
||||||
app:layout_constrainedWidth="true"
|
|
||||||
app:layout_constraintWidth_min="48dp"
|
|
||||||
app:layout_constraintHeight_min="48dp"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/cancel"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/remove_text">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center|bottom"
|
|
||||||
style="@style/MediaPlayer.OutlineButton"
|
|
||||||
android:text="@string/controls_media_dismiss_button"
|
|
||||||
/>
|
|
||||||
</FrameLayout>
|
|
||||||
</com.android.systemui.util.animation.TransitionLayout>
|
</com.android.systemui.util.animation.TransitionLayout>
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ class ColorSchemeTransition internal constructor(
|
|||||||
mediaViewHolder.albumView.backgroundTintList = colorList
|
mediaViewHolder.albumView.backgroundTintList = colorList
|
||||||
mediaViewHolder.seamlessIcon.imageTintList = colorList
|
mediaViewHolder.seamlessIcon.imageTintList = colorList
|
||||||
mediaViewHolder.seamlessText.setTextColor(surfaceColor)
|
mediaViewHolder.seamlessText.setTextColor(surfaceColor)
|
||||||
mediaViewHolder.dismissText.setTextColor(surfaceColor)
|
mediaViewHolder.gutsViewHolder.setSurfaceColor(surfaceColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
val accentPrimary = colorTransitionFactory(
|
val accentPrimary = colorTransitionFactory(
|
||||||
@@ -113,9 +113,7 @@ class ColorSchemeTransition internal constructor(
|
|||||||
val accentColorList = ColorStateList.valueOf(accentPrimary)
|
val accentColorList = ColorStateList.valueOf(accentPrimary)
|
||||||
mediaViewHolder.actionPlayPause.backgroundTintList = accentColorList
|
mediaViewHolder.actionPlayPause.backgroundTintList = accentColorList
|
||||||
mediaViewHolder.seamlessButton.backgroundTintList = accentColorList
|
mediaViewHolder.seamlessButton.backgroundTintList = accentColorList
|
||||||
mediaViewHolder.settings.imageTintList = accentColorList
|
mediaViewHolder.gutsViewHolder.setAccentPrimaryColor(accentPrimary)
|
||||||
mediaViewHolder.cancelText.backgroundTintList = accentColorList
|
|
||||||
mediaViewHolder.dismissText.backgroundTintList = accentColorList
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val textPrimary = colorTransitionFactory(
|
val textPrimary = colorTransitionFactory(
|
||||||
@@ -126,13 +124,12 @@ class ColorSchemeTransition internal constructor(
|
|||||||
val textColorList = ColorStateList.valueOf(textPrimary)
|
val textColorList = ColorStateList.valueOf(textPrimary)
|
||||||
mediaViewHolder.seekBar.thumb.setTintList(textColorList)
|
mediaViewHolder.seekBar.thumb.setTintList(textColorList)
|
||||||
mediaViewHolder.seekBar.progressTintList = textColorList
|
mediaViewHolder.seekBar.progressTintList = textColorList
|
||||||
mediaViewHolder.longPressText.setTextColor(textColorList)
|
|
||||||
mediaViewHolder.cancelText.setTextColor(textColorList)
|
|
||||||
mediaViewHolder.scrubbingElapsedTimeView.setTextColor(textColorList)
|
mediaViewHolder.scrubbingElapsedTimeView.setTextColor(textColorList)
|
||||||
mediaViewHolder.scrubbingTotalTimeView.setTextColor(textColorList)
|
mediaViewHolder.scrubbingTotalTimeView.setTextColor(textColorList)
|
||||||
for (button in mediaViewHolder.getTransparentActionButtons()) {
|
for (button in mediaViewHolder.getTransparentActionButtons()) {
|
||||||
button.imageTintList = textColorList
|
button.imageTintList = textColorList
|
||||||
}
|
}
|
||||||
|
mediaViewHolder.gutsViewHolder.setTextPrimaryColor(textPrimary)
|
||||||
}
|
}
|
||||||
|
|
||||||
val textPrimaryInverse = colorTransitionFactory(
|
val textPrimaryInverse = colorTransitionFactory(
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.media
|
||||||
|
|
||||||
|
import android.content.res.ColorStateList
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageButton
|
||||||
|
import android.widget.TextView
|
||||||
|
import com.android.systemui.R
|
||||||
|
import com.android.systemui.monet.ColorScheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A view holder for the guts menu of a media player. The guts are shown when the user long-presses
|
||||||
|
* on the media player.
|
||||||
|
*
|
||||||
|
* Both [MediaViewHolder] and [RecommendationViewHolder] use the same guts menu layout, so this
|
||||||
|
* class helps share logic between the two.
|
||||||
|
*/
|
||||||
|
class GutsViewHolder constructor(itemView: View) {
|
||||||
|
val gutsText: TextView = itemView.requireViewById(R.id.remove_text)
|
||||||
|
val cancel: View = itemView.requireViewById(R.id.cancel)
|
||||||
|
val cancelText: TextView = itemView.requireViewById(R.id.cancel_text)
|
||||||
|
val dismiss: ViewGroup = itemView.requireViewById(R.id.dismiss)
|
||||||
|
val dismissText: TextView = itemView.requireViewById(R.id.dismiss_text)
|
||||||
|
val settings: ImageButton = itemView.requireViewById(R.id.settings)
|
||||||
|
|
||||||
|
/** Marquees the main text of the guts menu. */
|
||||||
|
fun marquee(start: Boolean, delay: Long, tag: String) {
|
||||||
|
val gutsTextHandler = gutsText.handler
|
||||||
|
if (gutsTextHandler == null) {
|
||||||
|
Log.d(tag, "marquee while longPressText.getHandler() is null", Exception())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
gutsTextHandler.postDelayed( { gutsText.isSelected = start }, delay)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the right colors on all the guts views based on the given [ColorScheme]. */
|
||||||
|
fun setColors(colorScheme: ColorScheme) {
|
||||||
|
setSurfaceColor(surfaceFromScheme(colorScheme))
|
||||||
|
setTextPrimaryColor(textPrimaryFromScheme(colorScheme))
|
||||||
|
setAccentPrimaryColor(accentPrimaryFromScheme(colorScheme))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the surface color on all guts views that use it. */
|
||||||
|
fun setSurfaceColor(surfaceColor: Int) {
|
||||||
|
dismissText.setTextColor(surfaceColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the primary accent color on all guts views that use it. */
|
||||||
|
fun setAccentPrimaryColor(accentPrimary: Int) {
|
||||||
|
val accentColorList = ColorStateList.valueOf(accentPrimary)
|
||||||
|
settings.imageTintList = accentColorList
|
||||||
|
cancelText.backgroundTintList = accentColorList
|
||||||
|
dismissText.backgroundTintList = accentColorList
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the primary text color on all guts views that use it. */
|
||||||
|
fun setTextPrimaryColor(textPrimary: Int) {
|
||||||
|
val textColorList = ColorStateList.valueOf(textPrimary)
|
||||||
|
gutsText.setTextColor(textColorList)
|
||||||
|
cancelText.setTextColor(textColorList)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val ids = setOf(
|
||||||
|
R.id.remove_text,
|
||||||
|
R.id.cancel,
|
||||||
|
R.id.dismiss,
|
||||||
|
R.id.settings
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -336,17 +336,6 @@ public class MediaControlPanel {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
vh.getCancel().setOnClickListener(v -> {
|
|
||||||
if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
|
||||||
closeGuts();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
vh.getSettings().setOnClickListener(v -> {
|
|
||||||
if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
|
||||||
mLogger.logLongPressSettings(mUid, mPackageName, mInstanceId);
|
|
||||||
mActivityStarter.startActivity(SETTINGS_INTENT, true /* dismissShade */);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
TextView titleText = mMediaViewHolder.getTitleText();
|
TextView titleText = mMediaViewHolder.getTitleText();
|
||||||
TextView artistText = mMediaViewHolder.getArtistText();
|
TextView artistText = mMediaViewHolder.getArtistText();
|
||||||
@@ -391,17 +380,6 @@ public class MediaControlPanel {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mRecommendationViewHolder.getCancel().setOnClickListener(v -> {
|
|
||||||
if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
|
||||||
closeGuts();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mRecommendationViewHolder.getSettings().setOnClickListener(v -> {
|
|
||||||
if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
|
||||||
mLogger.logLongPressSettings(mUid, mPackageName, mInstanceId);
|
|
||||||
mActivityStarter.startActivity(SETTINGS_INTENT, true /* dismissShade */);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Bind this player view based on the data given. */
|
/** Bind this player view based on the data given. */
|
||||||
@@ -461,7 +439,7 @@ public class MediaControlPanel {
|
|||||||
mBackgroundExecutor.execute(() -> mSeekBarViewModel.updateController(controller));
|
mBackgroundExecutor.execute(() -> mSeekBarViewModel.updateController(controller));
|
||||||
|
|
||||||
bindOutputSwitcherChip(data);
|
bindOutputSwitcherChip(data);
|
||||||
bindLongPressMenu(data);
|
bindGutsMenuForPlayer(data);
|
||||||
bindScrubbingTime(data);
|
bindScrubbingTime(data);
|
||||||
bindActionButtons(data);
|
bindActionButtons(data);
|
||||||
|
|
||||||
@@ -531,24 +509,8 @@ public class MediaControlPanel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindLongPressMenu(MediaData data) {
|
private void bindGutsMenuForPlayer(MediaData data) {
|
||||||
boolean isDismissible = data.isClearable();
|
Runnable onDismissClickedRunnable = () -> {
|
||||||
String dismissText;
|
|
||||||
if (isDismissible) {
|
|
||||||
dismissText = mContext.getString(R.string.controls_media_close_session, data.getApp());
|
|
||||||
} else {
|
|
||||||
dismissText = mContext.getString(R.string.controls_media_active_session);
|
|
||||||
}
|
|
||||||
mMediaViewHolder.getLongPressText().setText(dismissText);
|
|
||||||
|
|
||||||
// Dismiss button
|
|
||||||
mMediaViewHolder.getDismissText().setAlpha(isDismissible ? 1 : DISABLED_ALPHA);
|
|
||||||
mMediaViewHolder.getDismiss().setEnabled(isDismissible);
|
|
||||||
mMediaViewHolder.getDismiss().setOnClickListener(v -> {
|
|
||||||
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return;
|
|
||||||
logSmartspaceCardReported(SMARTSPACE_CARD_DISMISS_EVENT);
|
|
||||||
mLogger.logLongPressDismiss(mUid, mPackageName, mInstanceId);
|
|
||||||
|
|
||||||
if (mKey != null) {
|
if (mKey != null) {
|
||||||
closeGuts();
|
closeGuts();
|
||||||
if (!mMediaDataManagerLazy.get().dismissMediaData(mKey,
|
if (!mMediaDataManagerLazy.get().dismissMediaData(mKey,
|
||||||
@@ -561,7 +523,13 @@ public class MediaControlPanel {
|
|||||||
Log.w(TAG, "Dismiss media with null notification. Token uid="
|
Log.w(TAG, "Dismiss media with null notification. Token uid="
|
||||||
+ data.getToken().getUid());
|
+ data.getToken().getUid());
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
bindGutsMenuCommon(
|
||||||
|
/* isDismissible= */ data.isClearable(),
|
||||||
|
data.getApp(),
|
||||||
|
mMediaViewHolder.getGutsViewHolder(),
|
||||||
|
onDismissClickedRunnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean bindSongMetadata(MediaData data) {
|
private boolean bindSongMetadata(MediaData data) {
|
||||||
@@ -1087,14 +1055,9 @@ public class MediaControlPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mSmartspaceMediaItemsCount = uiComponentIndex;
|
mSmartspaceMediaItemsCount = uiComponentIndex;
|
||||||
// Set up long press to show guts setting panel.
|
|
||||||
mRecommendationViewHolder.getDismiss().setOnClickListener(v -> {
|
|
||||||
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return;
|
|
||||||
|
|
||||||
mLogger.logLongPressDismiss(mUid, mPackageName, mInstanceId);
|
// Guts
|
||||||
logSmartspaceCardReported(
|
Runnable onDismissClickedRunnable = () -> {
|
||||||
761 // SMARTSPACE_CARD_DISMISS
|
|
||||||
);
|
|
||||||
closeGuts();
|
closeGuts();
|
||||||
mMediaDataManagerLazy.get().dismissSmartspaceRecommendation(
|
mMediaDataManagerLazy.get().dismissSmartspaceRecommendation(
|
||||||
data.getTargetId(), MediaViewController.GUTS_ANIMATION_DURATION + 100L);
|
data.getTargetId(), MediaViewController.GUTS_ANIMATION_DURATION + 100L);
|
||||||
@@ -1114,7 +1077,12 @@ public class MediaControlPanel {
|
|||||||
} else {
|
} else {
|
||||||
mBroadcastSender.sendBroadcast(dismissIntent);
|
mBroadcastSender.sendBroadcast(dismissIntent);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
bindGutsMenuCommon(
|
||||||
|
/* isDismissible= */ true,
|
||||||
|
appName.toString(),
|
||||||
|
mRecommendationViewHolder.getGutsViewHolder(),
|
||||||
|
onDismissClickedRunnable);
|
||||||
|
|
||||||
mController = null;
|
mController = null;
|
||||||
if (mMetadataAnimationHandler == null || !mMetadataAnimationHandler.isRunning()) {
|
if (mMetadataAnimationHandler == null || !mMetadataAnimationHandler.isRunning()) {
|
||||||
@@ -1145,6 +1113,49 @@ public class MediaControlPanel {
|
|||||||
(title) -> title.setTextColor(textPrimaryColor));
|
(title) -> title.setTextColor(textPrimaryColor));
|
||||||
mRecommendationViewHolder.getMediaSubtitles().forEach(
|
mRecommendationViewHolder.getMediaSubtitles().forEach(
|
||||||
(subtitle) -> subtitle.setTextColor(textSecondaryColor));
|
(subtitle) -> subtitle.setTextColor(textSecondaryColor));
|
||||||
|
|
||||||
|
mRecommendationViewHolder.getGutsViewHolder().setColors(colorScheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bindGutsMenuCommon(
|
||||||
|
boolean isDismissible,
|
||||||
|
String appName,
|
||||||
|
GutsViewHolder gutsViewHolder,
|
||||||
|
Runnable onDismissClickedRunnable) {
|
||||||
|
// Text
|
||||||
|
String text;
|
||||||
|
if (isDismissible) {
|
||||||
|
text = mContext.getString(R.string.controls_media_close_session, appName);
|
||||||
|
} else {
|
||||||
|
text = mContext.getString(R.string.controls_media_active_session);
|
||||||
|
}
|
||||||
|
gutsViewHolder.getGutsText().setText(text);
|
||||||
|
|
||||||
|
// Dismiss button
|
||||||
|
gutsViewHolder.getDismissText().setAlpha(isDismissible ? 1 : DISABLED_ALPHA);
|
||||||
|
gutsViewHolder.getDismiss().setEnabled(isDismissible);
|
||||||
|
gutsViewHolder.getDismiss().setOnClickListener(v -> {
|
||||||
|
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return;
|
||||||
|
logSmartspaceCardReported(SMARTSPACE_CARD_DISMISS_EVENT);
|
||||||
|
mLogger.logLongPressDismiss(mUid, mPackageName, mInstanceId);
|
||||||
|
|
||||||
|
onDismissClickedRunnable.run();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Cancel button
|
||||||
|
gutsViewHolder.getCancel().setOnClickListener(v -> {
|
||||||
|
if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
|
closeGuts();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Settings button
|
||||||
|
gutsViewHolder.getSettings().setOnClickListener(v -> {
|
||||||
|
if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
|
mLogger.logLongPressSettings(mUid, mPackageName, mInstanceId);
|
||||||
|
mActivityStarter.startActivity(SETTINGS_INTENT, /* dismissShade= */true);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -261,10 +261,7 @@ class MediaViewController @Inject constructor(
|
|||||||
TYPE.PLAYER -> MediaViewHolder.controlsIds
|
TYPE.PLAYER -> MediaViewHolder.controlsIds
|
||||||
TYPE.RECOMMENDATION -> RecommendationViewHolder.controlsIds
|
TYPE.RECOMMENDATION -> RecommendationViewHolder.controlsIds
|
||||||
}
|
}
|
||||||
val gutsIds = when (type) {
|
val gutsIds = GutsViewHolder.ids
|
||||||
TYPE.PLAYER -> MediaViewHolder.gutsIds
|
|
||||||
TYPE.RECOMMENDATION -> RecommendationViewHolder.gutsIds
|
|
||||||
}
|
|
||||||
controlsIds.forEach { id ->
|
controlsIds.forEach { id ->
|
||||||
viewState.widgetStates.get(id)?.let { state ->
|
viewState.widgetStates.get(id)?.let { state ->
|
||||||
// Make sure to use the unmodified state if guts are not visible.
|
// Make sure to use the unmodified state if guts are not visible.
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.android.systemui.media
|
package com.android.systemui.media
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@@ -56,13 +55,7 @@ class MediaViewHolder constructor(itemView: View) {
|
|||||||
val scrubbingTotalTimeView: TextView =
|
val scrubbingTotalTimeView: TextView =
|
||||||
itemView.requireViewById(R.id.media_scrubbing_total_time)
|
itemView.requireViewById(R.id.media_scrubbing_total_time)
|
||||||
|
|
||||||
// Settings screen
|
val gutsViewHolder = GutsViewHolder(itemView)
|
||||||
val longPressText = itemView.requireViewById<TextView>(R.id.remove_text)
|
|
||||||
val cancel = itemView.requireViewById<View>(R.id.cancel)
|
|
||||||
val cancelText = itemView.requireViewById<TextView>(R.id.cancel_text)
|
|
||||||
val dismiss = itemView.requireViewById<ViewGroup>(R.id.dismiss)
|
|
||||||
val dismissText = itemView.requireViewById<TextView>(R.id.dismiss_text)
|
|
||||||
val settings = itemView.requireViewById<ImageButton>(R.id.settings)
|
|
||||||
|
|
||||||
// Action Buttons
|
// Action Buttons
|
||||||
val actionPlayPause = itemView.requireViewById<ImageButton>(R.id.actionPlayPause)
|
val actionPlayPause = itemView.requireViewById<ImageButton>(R.id.actionPlayPause)
|
||||||
@@ -79,9 +72,9 @@ class MediaViewHolder constructor(itemView: View) {
|
|||||||
init {
|
init {
|
||||||
(player.background as IlluminationDrawable).let {
|
(player.background as IlluminationDrawable).let {
|
||||||
it.registerLightSource(seamless)
|
it.registerLightSource(seamless)
|
||||||
it.registerLightSource(cancel)
|
it.registerLightSource(gutsViewHolder.cancel)
|
||||||
it.registerLightSource(dismiss)
|
it.registerLightSource(gutsViewHolder.dismiss)
|
||||||
it.registerLightSource(settings)
|
it.registerLightSource(gutsViewHolder.settings)
|
||||||
it.registerLightSource(actionPlayPause)
|
it.registerLightSource(actionPlayPause)
|
||||||
it.registerLightSource(actionNext)
|
it.registerLightSource(actionNext)
|
||||||
it.registerLightSource(actionPrev)
|
it.registerLightSource(actionPrev)
|
||||||
@@ -122,12 +115,7 @@ class MediaViewHolder constructor(itemView: View) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun marquee(start: Boolean, delay: Long) {
|
fun marquee(start: Boolean, delay: Long) {
|
||||||
val longPressTextHandler = longPressText.getHandler()
|
gutsViewHolder.marquee(start, delay, TAG)
|
||||||
if (longPressTextHandler == null) {
|
|
||||||
Log.d(TAG, "marquee while longPressText.getHandler() is null", Exception())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
longPressTextHandler.postDelayed({ longPressText.setSelected(start) }, delay)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -172,12 +160,7 @@ class MediaViewHolder constructor(itemView: View) {
|
|||||||
R.id.media_scrubbing_elapsed_time,
|
R.id.media_scrubbing_elapsed_time,
|
||||||
R.id.media_scrubbing_total_time
|
R.id.media_scrubbing_total_time
|
||||||
)
|
)
|
||||||
val gutsIds = setOf(
|
|
||||||
R.id.remove_text,
|
|
||||||
R.id.cancel,
|
|
||||||
R.id.dismiss,
|
|
||||||
R.id.settings
|
|
||||||
)
|
|
||||||
|
|
||||||
// Buttons used for notification-based actions
|
// Buttons used for notification-based actions
|
||||||
val genericButtonIds = setOf(
|
val genericButtonIds = setOf(
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import android.widget.TextView
|
|||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.util.animation.TransitionLayout
|
import com.android.systemui.util.animation.TransitionLayout
|
||||||
|
|
||||||
|
private const val TAG = "RecommendationViewHolder"
|
||||||
|
|
||||||
/** ViewHolder for a Smartspace media recommendation. */
|
/** ViewHolder for a Smartspace media recommendation. */
|
||||||
class RecommendationViewHolder private constructor(itemView: View) {
|
class RecommendationViewHolder private constructor(itemView: View) {
|
||||||
|
|
||||||
@@ -52,26 +54,19 @@ class RecommendationViewHolder private constructor(itemView: View) {
|
|||||||
itemView.requireViewById(R.id.media_subtitle3)
|
itemView.requireViewById(R.id.media_subtitle3)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Settings/Guts screen
|
val gutsViewHolder = GutsViewHolder(itemView)
|
||||||
val longPressText = itemView.requireViewById<TextView>(R.id.remove_text)
|
|
||||||
val cancel = itemView.requireViewById<View>(R.id.cancel)
|
|
||||||
val dismiss = itemView.requireViewById<ViewGroup>(R.id.dismiss)
|
|
||||||
val dismissLabel = dismiss.getChildAt(0)
|
|
||||||
val settings = itemView.requireViewById<View>(R.id.settings)
|
|
||||||
val settingsText = itemView.requireViewById<TextView>(R.id.settings_text)
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
(recommendations.background as IlluminationDrawable).let { background ->
|
(recommendations.background as IlluminationDrawable).let { background ->
|
||||||
mediaCoverContainers.forEach { background.registerLightSource(it) }
|
mediaCoverContainers.forEach { background.registerLightSource(it) }
|
||||||
background.registerLightSource(cancel)
|
background.registerLightSource(gutsViewHolder.cancel)
|
||||||
background.registerLightSource(dismiss)
|
background.registerLightSource(gutsViewHolder.dismiss)
|
||||||
background.registerLightSource(dismissLabel)
|
background.registerLightSource(gutsViewHolder.settings)
|
||||||
background.registerLightSource(settings)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun marquee(start: Boolean, delay: Long) {
|
fun marquee(start: Boolean, delay: Long) {
|
||||||
longPressText.getHandler().postDelayed({ longPressText.setSelected(start) }, delay)
|
gutsViewHolder.marquee(start, delay, TAG)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -104,14 +99,12 @@ class RecommendationViewHolder private constructor(itemView: View) {
|
|||||||
R.id.media_cover1_container,
|
R.id.media_cover1_container,
|
||||||
R.id.media_cover2_container,
|
R.id.media_cover2_container,
|
||||||
R.id.media_cover3_container,
|
R.id.media_cover3_container,
|
||||||
)
|
R.id.media_title1,
|
||||||
|
R.id.media_title2,
|
||||||
// Res Ids for the components on the guts panel.
|
R.id.media_title3,
|
||||||
val gutsIds = setOf(
|
R.id.media_subtitle1,
|
||||||
R.id.remove_text,
|
R.id.media_subtitle2,
|
||||||
R.id.cancel,
|
R.id.media_subtitle3
|
||||||
R.id.dismiss,
|
|
||||||
R.id.settings
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,6 @@ import org.mockito.Mockito.`when` as whenever
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.Animatable2
|
import android.graphics.drawable.Animatable2
|
||||||
import android.graphics.drawable.AnimatedVectorDrawable
|
import android.graphics.drawable.AnimatedVectorDrawable
|
||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
@@ -35,7 +34,6 @@ import android.media.MediaMetadata
|
|||||||
import android.media.session.MediaSession
|
import android.media.session.MediaSession
|
||||||
import android.media.session.PlaybackState
|
import android.media.session.PlaybackState
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
|
||||||
import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS
|
import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper
|
import android.testing.TestableLooper
|
||||||
@@ -111,6 +109,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var activityStarter: ActivityStarter
|
@Mock private lateinit var activityStarter: ActivityStarter
|
||||||
@Mock private lateinit var broadcastSender: BroadcastSender
|
@Mock private lateinit var broadcastSender: BroadcastSender
|
||||||
|
|
||||||
|
@Mock private lateinit var gutsViewHolder: GutsViewHolder
|
||||||
@Mock private lateinit var viewHolder: MediaViewHolder
|
@Mock private lateinit var viewHolder: MediaViewHolder
|
||||||
@Mock private lateinit var view: TransitionLayout
|
@Mock private lateinit var view: TransitionLayout
|
||||||
@Mock private lateinit var seekBarViewModel: SeekBarViewModel
|
@Mock private lateinit var seekBarViewModel: SeekBarViewModel
|
||||||
@@ -145,8 +144,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
private lateinit var scrubbingElapsedTimeView: TextView
|
private lateinit var scrubbingElapsedTimeView: TextView
|
||||||
private lateinit var scrubbingTotalTimeView: TextView
|
private lateinit var scrubbingTotalTimeView: TextView
|
||||||
private lateinit var actionsTopBarrier: Barrier
|
private lateinit var actionsTopBarrier: Barrier
|
||||||
@Mock private lateinit var longPressText: TextView
|
@Mock private lateinit var gutsText: TextView
|
||||||
@Mock private lateinit var handler: Handler
|
|
||||||
@Mock private lateinit var mockAnimator: AnimatorSet
|
@Mock private lateinit var mockAnimator: AnimatorSet
|
||||||
private lateinit var settings: ImageButton
|
private lateinit var settings: ImageButton
|
||||||
private lateinit var cancel: View
|
private lateinit var cancel: View
|
||||||
@@ -228,6 +226,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initGutsViewHolderMocks()
|
||||||
initMediaViewHolderMocks()
|
initMediaViewHolderMocks()
|
||||||
|
|
||||||
// Create media session
|
// Create media session
|
||||||
@@ -272,6 +271,20 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initGutsViewHolderMocks() {
|
||||||
|
settings = ImageButton(context)
|
||||||
|
cancel = View(context)
|
||||||
|
cancelText = TextView(context)
|
||||||
|
dismiss = FrameLayout(context)
|
||||||
|
dismissText = TextView(context)
|
||||||
|
whenever(gutsViewHolder.gutsText).thenReturn(gutsText)
|
||||||
|
whenever(gutsViewHolder.settings).thenReturn(settings)
|
||||||
|
whenever(gutsViewHolder.cancel).thenReturn(cancel)
|
||||||
|
whenever(gutsViewHolder.cancelText).thenReturn(cancelText)
|
||||||
|
whenever(gutsViewHolder.dismiss).thenReturn(dismiss)
|
||||||
|
whenever(gutsViewHolder.dismissText).thenReturn(dismissText)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize elements in media view holder
|
* Initialize elements in media view holder
|
||||||
*/
|
*/
|
||||||
@@ -292,11 +305,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
seamlessIcon = ImageView(context)
|
seamlessIcon = ImageView(context)
|
||||||
seamlessText = TextView(context)
|
seamlessText = TextView(context)
|
||||||
seekBar = SeekBar(context).also { it.id = R.id.media_progress_bar }
|
seekBar = SeekBar(context).also { it.id = R.id.media_progress_bar }
|
||||||
settings = ImageButton(context)
|
|
||||||
cancel = View(context)
|
|
||||||
cancelText = TextView(context)
|
|
||||||
dismiss = FrameLayout(context)
|
|
||||||
dismissText = TextView(context)
|
|
||||||
|
|
||||||
action0 = ImageButton(context).also { it.setId(R.id.action0) }
|
action0 = ImageButton(context).also { it.setId(R.id.action0) }
|
||||||
action1 = ImageButton(context).also { it.setId(R.id.action1) }
|
action1 = ImageButton(context).also { it.setId(R.id.action1) }
|
||||||
@@ -341,6 +349,8 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
whenever(viewHolder.scrubbingElapsedTimeView).thenReturn(scrubbingElapsedTimeView)
|
whenever(viewHolder.scrubbingElapsedTimeView).thenReturn(scrubbingElapsedTimeView)
|
||||||
whenever(viewHolder.scrubbingTotalTimeView).thenReturn(scrubbingTotalTimeView)
|
whenever(viewHolder.scrubbingTotalTimeView).thenReturn(scrubbingTotalTimeView)
|
||||||
|
|
||||||
|
whenever(viewHolder.gutsViewHolder).thenReturn(gutsViewHolder)
|
||||||
|
|
||||||
// Transition View
|
// Transition View
|
||||||
whenever(view.parent).thenReturn(transitionParent)
|
whenever(view.parent).thenReturn(transitionParent)
|
||||||
whenever(view.rootView).thenReturn(transitionParent)
|
whenever(view.rootView).thenReturn(transitionParent)
|
||||||
@@ -363,15 +373,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
whenever(viewHolder.action4).thenReturn(action4)
|
whenever(viewHolder.action4).thenReturn(action4)
|
||||||
whenever(viewHolder.getAction(R.id.action4)).thenReturn(action4)
|
whenever(viewHolder.getAction(R.id.action4)).thenReturn(action4)
|
||||||
|
|
||||||
// Long press menu
|
|
||||||
whenever(viewHolder.longPressText).thenReturn(longPressText)
|
|
||||||
whenever(longPressText.handler).thenReturn(handler)
|
|
||||||
whenever(viewHolder.settings).thenReturn(settings)
|
|
||||||
whenever(viewHolder.cancel).thenReturn(cancel)
|
|
||||||
whenever(viewHolder.cancelText).thenReturn(cancelText)
|
|
||||||
whenever(viewHolder.dismiss).thenReturn(dismiss)
|
|
||||||
whenever(viewHolder.dismissText).thenReturn(dismissText)
|
|
||||||
|
|
||||||
whenever(viewHolder.actionsTopBarrier).thenReturn(actionsTopBarrier)
|
whenever(viewHolder.actionsTopBarrier).thenReturn(actionsTopBarrier)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,10 +405,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
listOf(recSubtitle1, recSubtitle2, recSubtitle3)
|
listOf(recSubtitle1, recSubtitle2, recSubtitle3)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Long press menu
|
whenever(recommendationViewHolder.gutsViewHolder).thenReturn(gutsViewHolder)
|
||||||
whenever(recommendationViewHolder.settings).thenReturn(settings)
|
|
||||||
whenever(recommendationViewHolder.cancel).thenReturn(cancel)
|
|
||||||
whenever(recommendationViewHolder.dismiss).thenReturn(dismiss)
|
|
||||||
|
|
||||||
val actionIcon = Icon.createWithResource(context, R.drawable.ic_android)
|
val actionIcon = Icon.createWithResource(context, R.drawable.ic_android)
|
||||||
whenever(smartspaceAction.icon).thenReturn(actionIcon)
|
whenever(smartspaceAction.icon).thenReturn(actionIcon)
|
||||||
@@ -968,8 +966,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
assertThat(seamless.isEnabled()).isFalse()
|
assertThat(seamless.isEnabled()).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ***** Guts tests for the player ***** */
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun longClick_gutsClosed() {
|
fun player_longClickWhenGutsClosed_gutsOpens() {
|
||||||
player.attachPlayer(viewHolder)
|
player.attachPlayer(viewHolder)
|
||||||
player.bindPlayer(mediaData, KEY)
|
player.bindPlayer(mediaData, KEY)
|
||||||
whenever(mediaViewController.isGutsVisible).thenReturn(false)
|
whenever(mediaViewController.isGutsVisible).thenReturn(false)
|
||||||
@@ -983,7 +983,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun longClick_gutsOpen() {
|
fun player_longClickWhenGutsOpen_gutsCloses() {
|
||||||
player.attachPlayer(viewHolder)
|
player.attachPlayer(viewHolder)
|
||||||
whenever(mediaViewController.isGutsVisible).thenReturn(true)
|
whenever(mediaViewController.isGutsVisible).thenReturn(true)
|
||||||
|
|
||||||
@@ -996,8 +996,9 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun cancelButtonClick_animation() {
|
fun player_cancelButtonClick_animation() {
|
||||||
player.attachPlayer(viewHolder)
|
player.attachPlayer(viewHolder)
|
||||||
|
player.bindPlayer(mediaData, KEY)
|
||||||
|
|
||||||
cancel.callOnClick()
|
cancel.callOnClick()
|
||||||
|
|
||||||
@@ -1005,7 +1006,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun settingsButtonClick() {
|
fun player_settingsButtonClick() {
|
||||||
player.attachPlayer(viewHolder)
|
player.attachPlayer(viewHolder)
|
||||||
player.bindPlayer(mediaData, KEY)
|
player.bindPlayer(mediaData, KEY)
|
||||||
|
|
||||||
@@ -1019,7 +1020,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun dismissButtonClick() {
|
fun player_dismissButtonClick() {
|
||||||
val mediaKey = "key for dismissal"
|
val mediaKey = "key for dismissal"
|
||||||
player.attachPlayer(viewHolder)
|
player.attachPlayer(viewHolder)
|
||||||
val state = mediaData.copy(notificationKey = KEY)
|
val state = mediaData.copy(notificationKey = KEY)
|
||||||
@@ -1032,7 +1033,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun dismissButtonDisabled() {
|
fun player_dismissButtonDisabled() {
|
||||||
val mediaKey = "key for dismissal"
|
val mediaKey = "key for dismissal"
|
||||||
player.attachPlayer(viewHolder)
|
player.attachPlayer(viewHolder)
|
||||||
val state = mediaData.copy(isClearable = false, notificationKey = KEY)
|
val state = mediaData.copy(isClearable = false, notificationKey = KEY)
|
||||||
@@ -1042,7 +1043,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun dismissButtonClick_notInManager() {
|
fun player_dismissButtonClick_notInManager() {
|
||||||
val mediaKey = "key for dismissal"
|
val mediaKey = "key for dismissal"
|
||||||
whenever(mediaDataManager.dismissMediaData(eq(mediaKey), anyLong())).thenReturn(false)
|
whenever(mediaDataManager.dismissMediaData(eq(mediaKey), anyLong())).thenReturn(false)
|
||||||
|
|
||||||
@@ -1057,6 +1058,76 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
verify(mediaCarouselController).removePlayer(eq(mediaKey), eq(false), eq(false))
|
verify(mediaCarouselController).removePlayer(eq(mediaKey), eq(false), eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ***** END guts tests for the player ***** */
|
||||||
|
|
||||||
|
/* ***** Guts tests for the recommendations ***** */
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun recommendations_longClickWhenGutsClosed_gutsOpens() {
|
||||||
|
player.attachRecommendation(recommendationViewHolder)
|
||||||
|
player.bindRecommendation(smartspaceData)
|
||||||
|
whenever(mediaViewController.isGutsVisible).thenReturn(false)
|
||||||
|
|
||||||
|
val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
|
||||||
|
verify(viewHolder.player).onLongClickListener = captor.capture()
|
||||||
|
|
||||||
|
captor.value.onLongClick(viewHolder.player)
|
||||||
|
verify(mediaViewController).openGuts()
|
||||||
|
verify(logger).logLongPressOpen(anyInt(), eq(PACKAGE), eq(instanceId))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun recommendations_longClickWhenGutsOpen_gutsCloses() {
|
||||||
|
player.attachRecommendation(recommendationViewHolder)
|
||||||
|
player.bindRecommendation(smartspaceData)
|
||||||
|
whenever(mediaViewController.isGutsVisible).thenReturn(true)
|
||||||
|
|
||||||
|
val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
|
||||||
|
verify(viewHolder.player).onLongClickListener = captor.capture()
|
||||||
|
|
||||||
|
captor.value.onLongClick(viewHolder.player)
|
||||||
|
verify(mediaViewController, never()).openGuts()
|
||||||
|
verify(mediaViewController).closeGuts(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun recommendations_cancelButtonClick_animation() {
|
||||||
|
player.attachRecommendation(recommendationViewHolder)
|
||||||
|
player.bindRecommendation(smartspaceData)
|
||||||
|
|
||||||
|
cancel.callOnClick()
|
||||||
|
|
||||||
|
verify(mediaViewController).closeGuts(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun recommendations_settingsButtonClick() {
|
||||||
|
player.attachRecommendation(recommendationViewHolder)
|
||||||
|
player.bindRecommendation(smartspaceData)
|
||||||
|
|
||||||
|
settings.callOnClick()
|
||||||
|
verify(logger).logLongPressSettings(anyInt(), eq(PACKAGE), eq(instanceId))
|
||||||
|
|
||||||
|
val captor = ArgumentCaptor.forClass(Intent::class.java)
|
||||||
|
verify(activityStarter).startActivity(captor.capture(), eq(true))
|
||||||
|
|
||||||
|
assertThat(captor.value.action).isEqualTo(ACTION_MEDIA_CONTROLS_SETTINGS)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun recommendations_dismissButtonClick() {
|
||||||
|
val mediaKey = "key for dismissal"
|
||||||
|
player.attachRecommendation(recommendationViewHolder)
|
||||||
|
player.bindRecommendation(smartspaceData.copy(targetId = mediaKey))
|
||||||
|
|
||||||
|
assertThat(dismiss.isEnabled).isEqualTo(true)
|
||||||
|
dismiss.callOnClick()
|
||||||
|
verify(logger).logLongPressDismiss(anyInt(), eq(PACKAGE), eq(instanceId))
|
||||||
|
verify(mediaDataManager).dismissSmartspaceRecommendation(eq(mediaKey), anyLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ***** END guts tests for the recommendations ***** */
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun actionPlayPauseClick_isLogged() {
|
fun actionPlayPauseClick_isLogged() {
|
||||||
val semanticActions = MediaButton(
|
val semanticActions = MediaButton(
|
||||||
|
|||||||
Reference in New Issue
Block a user