[Media Rec] Use the same long press menu for media player and media
recommendations. This defines a common GutsViewHolder that holds all the relevant views for the long press menu. Both MediaViewHolder and RecommendationViewHolder have a GutsViewHolder to perform common guts behavior. Fixes: 228961120 Bug: 223603970 Test: manual (see screenshots in bug) Test: MediaControlPanelTest Change-Id: I957e015697e3a4f0c55a2cba336cad4849a3dfff
This commit is contained in:
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_marginTop="0dp" />
|
||||
|
||||
<!-- Long press menu -->
|
||||
<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" />
|
||||
<include
|
||||
layout="@layout/media_long_press_menu" />
|
||||
|
||||
<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>
|
||||
|
||||
@@ -167,97 +167,7 @@
|
||||
android:layout_marginBottom="@dimen/qs_media_padding"
|
||||
/>
|
||||
|
||||
<!-- Long press menu -->
|
||||
<TextView
|
||||
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"/>
|
||||
<include
|
||||
layout="@layout/media_long_press_menu" />
|
||||
|
||||
<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>
|
||||
|
||||
@@ -103,7 +103,7 @@ class ColorSchemeTransition internal constructor(
|
||||
mediaViewHolder.albumView.backgroundTintList = colorList
|
||||
mediaViewHolder.seamlessIcon.imageTintList = colorList
|
||||
mediaViewHolder.seamlessText.setTextColor(surfaceColor)
|
||||
mediaViewHolder.dismissText.setTextColor(surfaceColor)
|
||||
mediaViewHolder.gutsViewHolder.setSurfaceColor(surfaceColor)
|
||||
}
|
||||
|
||||
val accentPrimary = colorTransitionFactory(
|
||||
@@ -113,9 +113,7 @@ class ColorSchemeTransition internal constructor(
|
||||
val accentColorList = ColorStateList.valueOf(accentPrimary)
|
||||
mediaViewHolder.actionPlayPause.backgroundTintList = accentColorList
|
||||
mediaViewHolder.seamlessButton.backgroundTintList = accentColorList
|
||||
mediaViewHolder.settings.imageTintList = accentColorList
|
||||
mediaViewHolder.cancelText.backgroundTintList = accentColorList
|
||||
mediaViewHolder.dismissText.backgroundTintList = accentColorList
|
||||
mediaViewHolder.gutsViewHolder.setAccentPrimaryColor(accentPrimary)
|
||||
}
|
||||
|
||||
val textPrimary = colorTransitionFactory(
|
||||
@@ -126,13 +124,12 @@ class ColorSchemeTransition internal constructor(
|
||||
val textColorList = ColorStateList.valueOf(textPrimary)
|
||||
mediaViewHolder.seekBar.thumb.setTintList(textColorList)
|
||||
mediaViewHolder.seekBar.progressTintList = textColorList
|
||||
mediaViewHolder.longPressText.setTextColor(textColorList)
|
||||
mediaViewHolder.cancelText.setTextColor(textColorList)
|
||||
mediaViewHolder.scrubbingElapsedTimeView.setTextColor(textColorList)
|
||||
mediaViewHolder.scrubbingTotalTimeView.setTextColor(textColorList)
|
||||
for (button in mediaViewHolder.getTransparentActionButtons()) {
|
||||
button.imageTintList = textColorList
|
||||
}
|
||||
mediaViewHolder.gutsViewHolder.setTextPrimaryColor(textPrimary)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
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 artistText = mMediaViewHolder.getArtistText();
|
||||
@@ -391,17 +380,6 @@ public class MediaControlPanel {
|
||||
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. */
|
||||
@@ -461,7 +439,7 @@ public class MediaControlPanel {
|
||||
mBackgroundExecutor.execute(() -> mSeekBarViewModel.updateController(controller));
|
||||
|
||||
bindOutputSwitcherChip(data);
|
||||
bindLongPressMenu(data);
|
||||
bindGutsMenuForPlayer(data);
|
||||
bindScrubbingTime(data);
|
||||
bindActionButtons(data);
|
||||
|
||||
@@ -531,24 +509,8 @@ public class MediaControlPanel {
|
||||
});
|
||||
}
|
||||
|
||||
private void bindLongPressMenu(MediaData data) {
|
||||
boolean isDismissible = data.isClearable();
|
||||
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);
|
||||
|
||||
private void bindGutsMenuForPlayer(MediaData data) {
|
||||
Runnable onDismissClickedRunnable = () -> {
|
||||
if (mKey != null) {
|
||||
closeGuts();
|
||||
if (!mMediaDataManagerLazy.get().dismissMediaData(mKey,
|
||||
@@ -561,7 +523,13 @@ public class MediaControlPanel {
|
||||
Log.w(TAG, "Dismiss media with null notification. Token uid="
|
||||
+ data.getToken().getUid());
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
bindGutsMenuCommon(
|
||||
/* isDismissible= */ data.isClearable(),
|
||||
data.getApp(),
|
||||
mMediaViewHolder.getGutsViewHolder(),
|
||||
onDismissClickedRunnable);
|
||||
}
|
||||
|
||||
private boolean bindSongMetadata(MediaData data) {
|
||||
@@ -1087,14 +1055,9 @@ public class MediaControlPanel {
|
||||
}
|
||||
|
||||
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);
|
||||
logSmartspaceCardReported(
|
||||
761 // SMARTSPACE_CARD_DISMISS
|
||||
);
|
||||
// Guts
|
||||
Runnable onDismissClickedRunnable = () -> {
|
||||
closeGuts();
|
||||
mMediaDataManagerLazy.get().dismissSmartspaceRecommendation(
|
||||
data.getTargetId(), MediaViewController.GUTS_ANIMATION_DURATION + 100L);
|
||||
@@ -1114,7 +1077,12 @@ public class MediaControlPanel {
|
||||
} else {
|
||||
mBroadcastSender.sendBroadcast(dismissIntent);
|
||||
}
|
||||
});
|
||||
};
|
||||
bindGutsMenuCommon(
|
||||
/* isDismissible= */ true,
|
||||
appName.toString(),
|
||||
mRecommendationViewHolder.getGutsViewHolder(),
|
||||
onDismissClickedRunnable);
|
||||
|
||||
mController = null;
|
||||
if (mMetadataAnimationHandler == null || !mMetadataAnimationHandler.isRunning()) {
|
||||
@@ -1145,6 +1113,49 @@ public class MediaControlPanel {
|
||||
(title) -> title.setTextColor(textPrimaryColor));
|
||||
mRecommendationViewHolder.getMediaSubtitles().forEach(
|
||||
(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.RECOMMENDATION -> RecommendationViewHolder.controlsIds
|
||||
}
|
||||
val gutsIds = when (type) {
|
||||
TYPE.PLAYER -> MediaViewHolder.gutsIds
|
||||
TYPE.RECOMMENDATION -> RecommendationViewHolder.gutsIds
|
||||
}
|
||||
val gutsIds = GutsViewHolder.ids
|
||||
controlsIds.forEach { id ->
|
||||
viewState.widgetStates.get(id)?.let { state ->
|
||||
// Make sure to use the unmodified state if guts are not visible.
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.systemui.media
|
||||
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -56,13 +55,7 @@ class MediaViewHolder constructor(itemView: View) {
|
||||
val scrubbingTotalTimeView: TextView =
|
||||
itemView.requireViewById(R.id.media_scrubbing_total_time)
|
||||
|
||||
// Settings screen
|
||||
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)
|
||||
val gutsViewHolder = GutsViewHolder(itemView)
|
||||
|
||||
// Action Buttons
|
||||
val actionPlayPause = itemView.requireViewById<ImageButton>(R.id.actionPlayPause)
|
||||
@@ -79,9 +72,9 @@ class MediaViewHolder constructor(itemView: View) {
|
||||
init {
|
||||
(player.background as IlluminationDrawable).let {
|
||||
it.registerLightSource(seamless)
|
||||
it.registerLightSource(cancel)
|
||||
it.registerLightSource(dismiss)
|
||||
it.registerLightSource(settings)
|
||||
it.registerLightSource(gutsViewHolder.cancel)
|
||||
it.registerLightSource(gutsViewHolder.dismiss)
|
||||
it.registerLightSource(gutsViewHolder.settings)
|
||||
it.registerLightSource(actionPlayPause)
|
||||
it.registerLightSource(actionNext)
|
||||
it.registerLightSource(actionPrev)
|
||||
@@ -122,12 +115,7 @@ class MediaViewHolder constructor(itemView: View) {
|
||||
}
|
||||
|
||||
fun marquee(start: Boolean, delay: Long) {
|
||||
val longPressTextHandler = longPressText.getHandler()
|
||||
if (longPressTextHandler == null) {
|
||||
Log.d(TAG, "marquee while longPressText.getHandler() is null", Exception())
|
||||
return
|
||||
}
|
||||
longPressTextHandler.postDelayed({ longPressText.setSelected(start) }, delay)
|
||||
gutsViewHolder.marquee(start, delay, TAG)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -172,12 +160,7 @@ class MediaViewHolder constructor(itemView: View) {
|
||||
R.id.media_scrubbing_elapsed_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
|
||||
val genericButtonIds = setOf(
|
||||
|
||||
@@ -24,6 +24,8 @@ import android.widget.TextView
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.util.animation.TransitionLayout
|
||||
|
||||
private const val TAG = "RecommendationViewHolder"
|
||||
|
||||
/** ViewHolder for a Smartspace media recommendation. */
|
||||
class RecommendationViewHolder private constructor(itemView: View) {
|
||||
|
||||
@@ -52,26 +54,19 @@ class RecommendationViewHolder private constructor(itemView: View) {
|
||||
itemView.requireViewById(R.id.media_subtitle3)
|
||||
)
|
||||
|
||||
// Settings/Guts screen
|
||||
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)
|
||||
val gutsViewHolder = GutsViewHolder(itemView)
|
||||
|
||||
init {
|
||||
(recommendations.background as IlluminationDrawable).let { background ->
|
||||
mediaCoverContainers.forEach { background.registerLightSource(it) }
|
||||
background.registerLightSource(cancel)
|
||||
background.registerLightSource(dismiss)
|
||||
background.registerLightSource(dismissLabel)
|
||||
background.registerLightSource(settings)
|
||||
background.registerLightSource(gutsViewHolder.cancel)
|
||||
background.registerLightSource(gutsViewHolder.dismiss)
|
||||
background.registerLightSource(gutsViewHolder.settings)
|
||||
}
|
||||
}
|
||||
|
||||
fun marquee(start: Boolean, delay: Long) {
|
||||
longPressText.getHandler().postDelayed({ longPressText.setSelected(start) }, delay)
|
||||
gutsViewHolder.marquee(start, delay, TAG)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -104,14 +99,12 @@ class RecommendationViewHolder private constructor(itemView: View) {
|
||||
R.id.media_cover1_container,
|
||||
R.id.media_cover2_container,
|
||||
R.id.media_cover3_container,
|
||||
)
|
||||
|
||||
// Res Ids for the components on the guts panel.
|
||||
val gutsIds = setOf(
|
||||
R.id.remove_text,
|
||||
R.id.cancel,
|
||||
R.id.dismiss,
|
||||
R.id.settings
|
||||
R.id.media_title1,
|
||||
R.id.media_title2,
|
||||
R.id.media_title3,
|
||||
R.id.media_subtitle1,
|
||||
R.id.media_subtitle2,
|
||||
R.id.media_subtitle3
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.mockito.Mockito.`when` as whenever
|
||||
import android.content.Intent
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Animatable2
|
||||
import android.graphics.drawable.AnimatedVectorDrawable
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
@@ -35,7 +34,6 @@ import android.media.MediaMetadata
|
||||
import android.media.session.MediaSession
|
||||
import android.media.session.PlaybackState
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.testing.TestableLooper
|
||||
@@ -111,6 +109,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
@Mock private lateinit var activityStarter: ActivityStarter
|
||||
@Mock private lateinit var broadcastSender: BroadcastSender
|
||||
|
||||
@Mock private lateinit var gutsViewHolder: GutsViewHolder
|
||||
@Mock private lateinit var viewHolder: MediaViewHolder
|
||||
@Mock private lateinit var view: TransitionLayout
|
||||
@Mock private lateinit var seekBarViewModel: SeekBarViewModel
|
||||
@@ -145,8 +144,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
private lateinit var scrubbingElapsedTimeView: TextView
|
||||
private lateinit var scrubbingTotalTimeView: TextView
|
||||
private lateinit var actionsTopBarrier: Barrier
|
||||
@Mock private lateinit var longPressText: TextView
|
||||
@Mock private lateinit var handler: Handler
|
||||
@Mock private lateinit var gutsText: TextView
|
||||
@Mock private lateinit var mockAnimator: AnimatorSet
|
||||
private lateinit var settings: ImageButton
|
||||
private lateinit var cancel: View
|
||||
@@ -228,6 +226,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
initGutsViewHolderMocks()
|
||||
initMediaViewHolderMocks()
|
||||
|
||||
// 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
|
||||
*/
|
||||
@@ -292,11 +305,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
seamlessIcon = ImageView(context)
|
||||
seamlessText = TextView(context)
|
||||
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) }
|
||||
action1 = ImageButton(context).also { it.setId(R.id.action1) }
|
||||
@@ -341,6 +349,8 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
whenever(viewHolder.scrubbingElapsedTimeView).thenReturn(scrubbingElapsedTimeView)
|
||||
whenever(viewHolder.scrubbingTotalTimeView).thenReturn(scrubbingTotalTimeView)
|
||||
|
||||
whenever(viewHolder.gutsViewHolder).thenReturn(gutsViewHolder)
|
||||
|
||||
// Transition View
|
||||
whenever(view.parent).thenReturn(transitionParent)
|
||||
whenever(view.rootView).thenReturn(transitionParent)
|
||||
@@ -363,15 +373,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
whenever(viewHolder.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)
|
||||
}
|
||||
|
||||
@@ -404,10 +405,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
listOf(recSubtitle1, recSubtitle2, recSubtitle3)
|
||||
)
|
||||
|
||||
// Long press menu
|
||||
whenever(recommendationViewHolder.settings).thenReturn(settings)
|
||||
whenever(recommendationViewHolder.cancel).thenReturn(cancel)
|
||||
whenever(recommendationViewHolder.dismiss).thenReturn(dismiss)
|
||||
whenever(recommendationViewHolder.gutsViewHolder).thenReturn(gutsViewHolder)
|
||||
|
||||
val actionIcon = Icon.createWithResource(context, R.drawable.ic_android)
|
||||
whenever(smartspaceAction.icon).thenReturn(actionIcon)
|
||||
@@ -968,8 +966,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
assertThat(seamless.isEnabled()).isFalse()
|
||||
}
|
||||
|
||||
/* ***** Guts tests for the player ***** */
|
||||
|
||||
@Test
|
||||
fun longClick_gutsClosed() {
|
||||
fun player_longClickWhenGutsClosed_gutsOpens() {
|
||||
player.attachPlayer(viewHolder)
|
||||
player.bindPlayer(mediaData, KEY)
|
||||
whenever(mediaViewController.isGutsVisible).thenReturn(false)
|
||||
@@ -983,7 +983,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun longClick_gutsOpen() {
|
||||
fun player_longClickWhenGutsOpen_gutsCloses() {
|
||||
player.attachPlayer(viewHolder)
|
||||
whenever(mediaViewController.isGutsVisible).thenReturn(true)
|
||||
|
||||
@@ -996,8 +996,9 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun cancelButtonClick_animation() {
|
||||
fun player_cancelButtonClick_animation() {
|
||||
player.attachPlayer(viewHolder)
|
||||
player.bindPlayer(mediaData, KEY)
|
||||
|
||||
cancel.callOnClick()
|
||||
|
||||
@@ -1005,7 +1006,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun settingsButtonClick() {
|
||||
fun player_settingsButtonClick() {
|
||||
player.attachPlayer(viewHolder)
|
||||
player.bindPlayer(mediaData, KEY)
|
||||
|
||||
@@ -1019,7 +1020,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dismissButtonClick() {
|
||||
fun player_dismissButtonClick() {
|
||||
val mediaKey = "key for dismissal"
|
||||
player.attachPlayer(viewHolder)
|
||||
val state = mediaData.copy(notificationKey = KEY)
|
||||
@@ -1032,7 +1033,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dismissButtonDisabled() {
|
||||
fun player_dismissButtonDisabled() {
|
||||
val mediaKey = "key for dismissal"
|
||||
player.attachPlayer(viewHolder)
|
||||
val state = mediaData.copy(isClearable = false, notificationKey = KEY)
|
||||
@@ -1042,7 +1043,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dismissButtonClick_notInManager() {
|
||||
fun player_dismissButtonClick_notInManager() {
|
||||
val mediaKey = "key for dismissal"
|
||||
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))
|
||||
}
|
||||
|
||||
/* ***** 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
|
||||
fun actionPlayPauseClick_isLogged() {
|
||||
val semanticActions = MediaButton(
|
||||
|
||||
Reference in New Issue
Block a user