diff options
| author | 2021-04-26 21:11:21 +0000 | |
|---|---|---|
| committer | 2021-04-26 21:11:21 +0000 | |
| commit | 4d4782aab748d069388d68563c274c63b59031da (patch) | |
| tree | b47e3e8d7ab1494b1afbb70ad29012d2bac49b35 | |
| parent | d56cd5e5aa119ac3934c4ed2c228132c17ad4764 (diff) | |
| parent | f685301e949231b4a28ee4ea2a586d0e27bf6417 (diff) | |
Merge "Add the guts control panel to Smartspace media recommendation card." into sc-dev
7 files changed, 193 insertions, 34 deletions
diff --git a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml index 7e944162fd0d..f4a743490181 100644 --- a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml +++ b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml @@ -18,6 +18,7 @@ <!-- Layout for media recommendations inside QSPanel carousel --> <com.android.systemui.util.animation.TransitionLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/media_recommendations" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -84,4 +85,99 @@ android:layout_width="@dimen/qs_aa_media_rec_icon_size" android:layout_height="@dimen/qs_aa_media_rec_icon_size" /> + <!-- Constraints are set here as they are the same regardless of host --> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/qs_media_panel_outer_padding" + android:layout_marginStart="@dimen/qs_media_panel_outer_padding" + android:layout_marginEnd="@dimen/qs_media_panel_outer_padding" + android:id="@+id/recommendation_text" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" + android:textColor="?android:attr/textColorSecondary" + android:text="@string/controls_media_title" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintBottom_toTopOf="@id/remove_text" + app:layout_constraintVertical_chainStyle="spread_inside"/> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/qs_media_panel_outer_padding" + android:layout_marginEnd="@dimen/qs_media_panel_outer_padding" + android:id="@+id/remove_text" + android:fontFamily="@*android:string/config_headlineFontFamily" + android:singleLine="true" + android:textColor="?android:attr/textColorPrimary" + android:text="@string/controls_media_close_session" + app:layout_constraintTop_toBottomOf="@id/recommendation_text" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintBottom_toTopOf="@id/settings"/> + + <FrameLayout + android:id="@+id/settings" + android:background="@drawable/qs_media_light_source" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/qs_media_panel_outer_padding" + android:paddingBottom="@dimen/qs_media_panel_outer_padding" + android:minWidth="48dp" + android:minHeight="48dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/remove_text"> + + <TextView + android:layout_gravity="bottom" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" + android:textColor="?android:attr/textColorPrimary" + android:text="@string/controls_media_settings_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_marginEnd="@dimen/qs_media_panel_outer_padding" + android:paddingBottom="@dimen/qs_media_panel_outer_padding" + android:minWidth="48dp" + android:minHeight="48dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/dismiss" > + + <TextView + android:layout_gravity="bottom" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" + android:textColor="?android:attr/textColorPrimary" + android:text="@string/cancel" /> + </FrameLayout> + + <FrameLayout + android:id="@+id/dismiss" + android:background="@drawable/qs_media_light_source" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="@dimen/qs_media_panel_outer_padding" + android:paddingBottom="@dimen/qs_media_panel_outer_padding" + android:minWidth="48dp" + android:minHeight="48dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent"> + + <TextView + android:layout_gravity="bottom" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" + android:textColor="?android:attr/textColorPrimary" + android:text="@string/controls_media_dismiss_button" + /> + </FrameLayout> + </com.android.systemui.util.animation.TransitionLayout>
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index 2ecd40578d68..c3c617c636da 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -319,7 +319,7 @@ class MediaCarouselController @Inject constructor( val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) newRecs.recommendationViewHolder?.recommendations?.setLayoutParams(lp) - newRecs.bindRecommendation(data, bgColor, { v -> removePlayer(key) }) + newRecs.bindRecommendation(data, bgColor) MediaPlayerData.addMediaPlayer(key, newRecs) updatePlayerToState(newRecs, noAnimation = true) reorderAllPlayers() @@ -348,11 +348,11 @@ class MediaCarouselController @Inject constructor( if (dismissMediaData) { // Inform the media manager of a potentially late dismissal - mediaManager.dismissMediaData(key, 0L) + mediaManager.dismissMediaData(key, 0L /* delaye */) } if (dismissRecommendation) { // Inform the media manager of a potentially late dismissal - mediaManager.dismissSmartspaceRecommendation() + mediaManager.dismissSmartspaceRecommendation(0L /* delay */) } } } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 94cb2dcedc38..e6eb3178bfe4 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -242,6 +242,21 @@ public class MediaControlPanel { TransitionLayout recommendations = vh.getRecommendations(); mMediaViewController.attach(recommendations, MediaViewController.TYPE.RECOMMENDATION); + + mRecommendationViewHolder.getRecommendations().setOnLongClickListener(v -> { + if (!mMediaViewController.isGutsVisible()) { + mMediaViewController.openGuts(); + return true; + } else { + return false; + } + }); + mRecommendationViewHolder.getCancel().setOnClickListener(v -> { + closeGuts(); + }); + mRecommendationViewHolder.getSettings().setOnClickListener(v -> { + mActivityStarter.startActivity(SETTINGS_INTENT, true /* dismissShade */); + }); } /** Bind this player view based on the data given. */ @@ -461,10 +476,7 @@ public class MediaControlPanel { } /** Bind this recommendation view based on the data given. */ - public void bindRecommendation( - @NonNull SmartspaceTarget target, - @NonNull int backgroundColor, - @Nullable View.OnClickListener callback) { + public void bindRecommendation(@NonNull SmartspaceTarget target, @NonNull int backgroundColor) { if (mRecommendationViewHolder == null) { return; } @@ -520,8 +532,10 @@ public class MediaControlPanel { mediaCoverImageView.setImageIcon(recommendation.getIcon()); // Set up the click listener if applicable. - setSmartspaceOnClickListener(mediaCoverImageView, recommendation, - target.getSmartspaceTargetId(), callback); + setSmartspaceRecItemOnClickListener(mediaCoverImageView, recommendation, + view -> mMediaDataManagerLazy + .get() + .dismissSmartspaceRecommendation(0L /* delay */)); setVisibleAndAlpha(expandedSet, mediaCoverItemsResIds.get(i), true); setVisibleAndAlpha(expandedSet, mediaLogoItemsResIds.get(i), true); @@ -529,6 +543,16 @@ public class MediaControlPanel { setVisibleAndAlpha(collapsedSet, mediaLogoItemsResIds.get(i), true); } + // Set up long press to show guts setting panel. + mRecommendationViewHolder.getDismiss().setOnClickListener(v -> { + closeGuts(); + mKeyguardDismissUtil.executeWhenUnlocked(() -> { + mMediaDataManagerLazy.get().dismissSmartspaceRecommendation( + MediaViewController.GUTS_ANIMATION_DURATION + 100L); + return true; + }, true /* requiresShadeOpen */); + }); + mController = null; mMediaViewController.refreshState(); } @@ -613,10 +637,9 @@ public class MediaControlPanel { set.setAlpha(actionId, visible ? 1.0f : 0.0f); } - private void setSmartspaceOnClickListener( + private void setSmartspaceRecItemOnClickListener( @NonNull View view, @NonNull SmartspaceAction action, - @NonNull String targetId, @Nullable View.OnClickListener callback) { if (view == null || action == null || action.getIntent() == null) { Log.e(TAG, "No tap action can be set up"); @@ -624,16 +647,6 @@ public class MediaControlPanel { } view.setOnClickListener(v -> { - // When media recommendation card is shown, there could be only one card. - SysUiStatsLog.write(SysUiStatsLog.SMARTSPACE_CARD_REPORTED, - 760, // SMARTSPACE_CARD_CLICK - targetId.hashCode(), - SysUiStatsLog - .SMART_SPACE_CARD_REPORTED__CARD_TYPE__HEADPHONE_MEDIA_RECOMMENDATIONS, - getSurfaceForSmartspaceLogging(mMediaViewController.getCurrentEndLocation()), - /* rank */ 1, - /* cardinality */ 1); - mActivityStarter.postStartActivityDismissingKeyguard( action.getIntent(), 0 /* delay */, diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt index 5f73ae0814c7..2bd7729f58d4 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt @@ -191,7 +191,7 @@ class MediaDataFilter @Inject constructor( mediaDataManager.setTimedOut(it, timedOut = true, forceUpdate = true) } if (hasSmartspace) { - mediaDataManager.dismissSmartspaceRecommendation() + mediaDataManager.dismissSmartspaceRecommendation(0L /* delay */) } } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 78071769043c..a0708617ef66 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -429,12 +429,13 @@ class MediaDataManager( * This will make the recommendation view to not be shown anymore during this headphone * connection session. */ - fun dismissSmartspaceRecommendation() { + fun dismissSmartspaceRecommendation(delay: Long) { Log.d(TAG, "Dismissing Smartspace media target") // Do not set smartspaceMediaTarget to null. So the instance is preserved during the entire // headphone connection, and will ONLY be set to null when headphones are disconnected. smartspaceMediaTarget?.let { - notifySmartspaceMediaDataRemoved(it.smartspaceTargetId) + foregroundExecutor.executeDelayed( + { notifySmartspaceMediaDataRemoved(it.smartspaceTargetId) }, delay) } } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt index e848e2fa0c08..f78556f18492 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt @@ -252,16 +252,30 @@ class MediaViewController @Inject constructor( * [TransitionViewState]. */ private fun setGutsViewState(viewState: TransitionViewState) { - PlayerViewHolder.controlsIds.forEach { id -> - viewState.widgetStates.get(id)?.let { state -> - // Make sure to use the unmodified state if guts are not visible - state.alpha = if (isGutsVisible) 0f else state.alpha - state.gone = if (isGutsVisible) true else state.gone + if (type == TYPE.PLAYER) { + PlayerViewHolder.controlsIds.forEach { id -> + viewState.widgetStates.get(id)?.let { state -> + // Make sure to use the unmodified state if guts are not visible. + state.alpha = if (isGutsVisible) 0f else state.alpha + state.gone = if (isGutsVisible) true else state.gone + } + } + PlayerViewHolder.gutsIds.forEach { id -> + viewState.widgetStates.get(id)?.alpha = if (isGutsVisible) 1f else 0f + viewState.widgetStates.get(id)?.gone = !isGutsVisible + } + } else { + RecommendationViewHolder.controlsIds.forEach { id -> + viewState.widgetStates.get(id)?.let { state -> + // Make sure to use the unmodified state if guts are not visible. + state.alpha = if (isGutsVisible) 0f else state.alpha + state.gone = if (isGutsVisible) true else state.gone + } + } + RecommendationViewHolder.gutsIds.forEach { id -> + viewState.widgetStates.get(id)?.alpha = if (isGutsVisible) 1f else 0f + viewState.widgetStates.get(id)?.gone = !isGutsVisible } - } - PlayerViewHolder.gutsIds.forEach { id -> - viewState.widgetStates.get(id)?.alpha = if (isGutsVisible) 1f else 0f - viewState.widgetStates.get(id)?.gone = !isGutsVisible } } diff --git a/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt index ac201a804e38..19c83bc83ac3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt @@ -20,6 +20,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView +import android.widget.TextView import androidx.annotation.IntegerRes import com.android.systemui.R import com.android.systemui.util.animation.TransitionLayout @@ -28,6 +29,8 @@ import com.android.systemui.util.animation.TransitionLayout class RecommendationViewHolder private constructor(itemView: View) { val recommendations = itemView as TransitionLayout + + // Recommendation screen val mediaCoverItems = listOf<ImageView>( itemView.requireViewById(R.id.media_cover1), itemView.requireViewById(R.id.media_cover2), @@ -49,16 +52,27 @@ class RecommendationViewHolder private constructor(itemView: View) { R.id.media_logo3, R.id.media_logo4) + // Settings/Guts screen + val cancel = itemView.requireViewById<View>(R.id.cancel) + val dismiss = itemView.requireViewById<ViewGroup>(R.id.dismiss) + val dismissLabel = dismiss.getChildAt(0) + val recommendationText = itemView.requireViewById<TextView>(R.id.recommendation_text) + val settings = itemView.requireViewById<View>(R.id.settings) + init { (recommendations.background as IlluminationDrawable).let { background -> mediaCoverItems.forEach { background.registerLightSource(it) } mediaLogoItems.forEach { background.registerLightSource(it) } + background.registerLightSource(cancel) + background.registerLightSource(dismiss) + background.registerLightSource(dismissLabel) + background.registerLightSource(settings) } } companion object { /** - * Creates a PlayerViewHolder. + * Creates a RecommendationViewHolder. * * @param inflater LayoutInflater to use to inflate the layout. * @param parent Parent of inflated view. @@ -76,5 +90,26 @@ class RecommendationViewHolder private constructor(itemView: View) { itemView.layoutDirection = View.LAYOUT_DIRECTION_LOCALE return RecommendationViewHolder(itemView) } + + // Res Ids for the control components on the recommendation view. + val controlsIds = setOf( + R.id.media_cover1, + R.id.media_cover2, + R.id.media_cover3, + R.id.media_cover4, + R.id.media_logo1, + R.id.media_logo2, + R.id.media_logo3, + R.id.media_logo4 + ) + + // Res Ids for the components on the guts panel. + val gutsIds = setOf( + R.id.recommendation_text, + R.id.remove_text, + R.id.cancel, + R.id.dismiss, + R.id.settings + ) } }
\ No newline at end of file |