Skip to content
Snippets Groups Projects
Commit b338a450 authored by Justin Weir's avatar Justin Weir Committed by Automerger Merge Worker
Browse files

Merge changes from topic "b224749799" into tm-dev am: 123c1b09 am: 7325f79b

parents cb5deeee 7325f79b
No related branches found
No related tags found
No related merge requests found
......@@ -837,7 +837,14 @@ public class MediaControlPanel {
scrubbingTimeViewsEnabled(semanticActions) && hideWhenScrubbing && mIsScrubbing;
boolean visible = mediaAction != null && !shouldBeHiddenDueToScrubbing;
setVisibleAndAlpha(expandedSet, buttonId, visible);
int notVisibleValue;
if ((buttonId == R.id.actionPrev && semanticActions.getReservePrev())
|| (buttonId == R.id.actionNext && semanticActions.getReserveNext())) {
notVisibleValue = ConstraintSet.INVISIBLE;
} else {
notVisibleValue = ConstraintSet.GONE;
}
setVisibleAndAlpha(expandedSet, buttonId, visible, notVisibleValue);
setVisibleAndAlpha(collapsedSet, buttonId, visible && showInCompact);
}
......@@ -1177,7 +1184,12 @@ public class MediaControlPanel {
}
private void setVisibleAndAlpha(ConstraintSet set, int actionId, boolean visible) {
set.setVisibility(actionId, visible ? ConstraintSet.VISIBLE : ConstraintSet.GONE);
setVisibleAndAlpha(set, actionId, visible, ConstraintSet.GONE);
}
private void setVisibleAndAlpha(ConstraintSet set, int actionId, boolean visible,
int notVisibleValue) {
set.setVisibility(actionId, visible ? ConstraintSet.VISIBLE : notVisibleValue);
set.setAlpha(actionId, visible ? 1.0f : 0.0f);
}
......
......@@ -149,23 +149,31 @@ data class MediaButton(
/**
* Play/pause button
*/
var playOrPause: MediaAction? = null,
val playOrPause: MediaAction? = null,
/**
* Next button, or custom action
*/
var nextOrCustom: MediaAction? = null,
val nextOrCustom: MediaAction? = null,
/**
* Previous button, or custom action
*/
var prevOrCustom: MediaAction? = null,
val prevOrCustom: MediaAction? = null,
/**
* First custom action space
*/
var custom0: MediaAction? = null,
val custom0: MediaAction? = null,
/**
* Second custom action space
*/
var custom1: MediaAction? = null
val custom1: MediaAction? = null,
/**
* Whether to reserve the empty space when the nextOrCustom is null
*/
val reserveNext: Boolean = false,
/**
* Whether to reserve the empty space when the prevOrCustom is null
*/
val reservePrev: Boolean = false
) {
fun getActionById(id: Int): MediaAction? {
return when (id) {
......
......@@ -173,10 +173,6 @@ class MediaDataManager(
// Maximum number of actions allowed in expanded view
@JvmField
val MAX_NOTIFICATION_ACTIONS = MediaViewHolder.genericButtonIds.size
/** Maximum number of [PlaybackState.CustomAction] buttons supported */
@JvmField
val MAX_CUSTOM_ACTIONS = 4
}
private val themeText = com.android.settingslib.Utils.getColorAttr(context,
......@@ -795,71 +791,74 @@ class MediaDataManager(
*/
private fun createActionsFromState(packageName: String, controller: MediaController):
MediaButton? {
val actions = MediaButton()
controller.playbackState?.let { state ->
// First, check for standard actions
actions.playOrPause = if (isConnectingState(state.state)) {
// Spinner needs to be animating to render anything. Start it here.
val drawable = context.getDrawable(
com.android.internal.R.drawable.progress_small_material)
(drawable as Animatable).start()
MediaAction(
drawable,
null, // no action to perform when clicked
context.getString(R.string.controls_media_button_connecting),
context.getDrawable(R.drawable.ic_media_connecting_container),
// Specify a rebind id to prevent the spinner from restarting on later binds.
com.android.internal.R.drawable.progress_small_material
)
} else if (isPlayingState(state.state)) {
getStandardAction(controller, state.actions, PlaybackState.ACTION_PAUSE)
} else {
getStandardAction(controller, state.actions, PlaybackState.ACTION_PLAY)
}
val prevButton = getStandardAction(controller, state.actions,
PlaybackState.ACTION_SKIP_TO_PREVIOUS)
val nextButton = getStandardAction(controller, state.actions,
PlaybackState.ACTION_SKIP_TO_NEXT)
// Then, check for custom actions
val customActions = MutableList<MediaAction?>(MAX_CUSTOM_ACTIONS) { null }
var customCount = 0
for (i in 0..(MAX_CUSTOM_ACTIONS - 1)) {
getCustomAction(state, packageName, controller, customCount)?.let {
customActions[customCount++] = it
}
}
// Finally, assign the remaining button slots: play/pause A B C D
// A = previous, else custom action (if not reserved)
// B = next, else custom action (if not reserved)
// C and D are always custom actions
val reservePrev = controller.extras?.getBoolean(
MediaConstants.SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV) == true
val reserveNext = controller.extras?.getBoolean(
MediaConstants.SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT) == true
var customIdx = 0
actions.prevOrCustom = if (prevButton != null) {
prevButton
} else if (!reservePrev) {
customActions[customIdx++]
} else {
null
}
actions.nextOrCustom = if (nextButton != null) {
nextButton
} else if (!reserveNext) {
customActions[customIdx++]
} else {
null
}
val state = controller.playbackState
if (state == null) {
return MediaButton()
}
// First, check for} standard actions
val playOrPause = if (isConnectingState(state.state)) {
// Spinner needs to be animating to render anything. Start it here.
val drawable = context.getDrawable(
com.android.internal.R.drawable.progress_small_material)
(drawable as Animatable).start()
MediaAction(
drawable,
null, // no action to perform when clicked
context.getString(R.string.controls_media_button_connecting),
context.getDrawable(R.drawable.ic_media_connecting_container),
// Specify a rebind id to prevent the spinner from restarting on later binds.
com.android.internal.R.drawable.progress_small_material
)
} else if (isPlayingState(state.state)) {
getStandardAction(controller, state.actions, PlaybackState.ACTION_PAUSE)
} else {
getStandardAction(controller, state.actions, PlaybackState.ACTION_PLAY)
}
val prevButton = getStandardAction(controller, state.actions,
PlaybackState.ACTION_SKIP_TO_PREVIOUS)
val nextButton = getStandardAction(controller, state.actions,
PlaybackState.ACTION_SKIP_TO_NEXT)
// Then, create a way to build any custom actions that will be needed
val customActions = state.customActions.asSequence().filterNotNull().map {
getCustomAction(state, packageName, controller, it)
}.iterator()
fun nextCustomAction() = if (customActions.hasNext()) customActions.next() else null
// Finally, assign the remaining button slots: play/pause A B C D
// A = previous, else custom action (if not reserved)
// B = next, else custom action (if not reserved)
// C and D are always custom actions
val reservePrev = controller.extras?.getBoolean(
MediaConstants.SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV) == true
val reserveNext = controller.extras?.getBoolean(
MediaConstants.SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT) == true
val prevOrCustom = if (prevButton != null) {
prevButton
} else if (!reservePrev) {
nextCustomAction()
} else {
null
}
actions.custom0 = customActions[customIdx++]
actions.custom1 = customActions[customIdx++]
val nextOrCustom = if (nextButton != null) {
nextButton
} else if (!reserveNext) {
nextCustomAction()
} else {
null
}
return actions
return MediaButton(
playOrPause,
nextOrCustom,
prevOrCustom,
nextCustomAction(),
nextCustomAction(),
reserveNext,
reservePrev
)
}
/**
......@@ -938,18 +937,12 @@ class MediaDataManager(
state: PlaybackState,
packageName: String,
controller: MediaController,
index: Int
): MediaAction? {
if (state.customActions.size <= index || state.customActions[index] == null) {
if (DEBUG) { Log.d(TAG, "not enough actions or action was null at $index") }
return null
}
val it = state.customActions[index]
customAction: PlaybackState.CustomAction
): MediaAction {
return MediaAction(
Icon.createWithResource(packageName, it.icon).loadDrawable(context),
{ controller.transportControls.sendCustomAction(it, it.extras) },
it.name,
Icon.createWithResource(packageName, customAction.icon).loadDrawable(context),
{ controller.transportControls.sendCustomAction(customAction, customAction.extras) },
customAction.name,
null
)
}
......
......@@ -448,6 +448,64 @@ public class MediaControlPanelTest : SysuiTestCase() {
verify(expandedSet).setVisibility(R.id.action4, ConstraintSet.GONE)
}
@Test
fun bindSemanticActions_reservedPrev() {
val icon = context.getDrawable(android.R.drawable.ic_media_play)
val bg = context.getDrawable(R.drawable.qs_media_round_button_background)
// Setup button state: no prev or next button and their slots reserved
val semanticActions = MediaButton(
playOrPause = MediaAction(icon, Runnable {}, "play", bg),
nextOrCustom = null,
prevOrCustom = null,
custom0 = MediaAction(icon, null, "custom 0", bg),
custom1 = MediaAction(icon, null, "custom 1", bg),
false,
true
)
val state = mediaData.copy(semanticActions = semanticActions)
player.attachPlayer(viewHolder)
player.bindPlayer(state, PACKAGE)
assertThat(actionPrev.isEnabled()).isFalse()
assertThat(actionPrev.drawable).isNull()
verify(expandedSet).setVisibility(R.id.actionPrev, ConstraintSet.INVISIBLE)
assertThat(actionNext.isEnabled()).isFalse()
assertThat(actionNext.drawable).isNull()
verify(expandedSet).setVisibility(R.id.actionNext, ConstraintSet.GONE)
}
@Test
fun bindSemanticActions_reservedNext() {
val icon = context.getDrawable(android.R.drawable.ic_media_play)
val bg = context.getDrawable(R.drawable.qs_media_round_button_background)
// Setup button state: no prev or next button and their slots reserved
val semanticActions = MediaButton(
playOrPause = MediaAction(icon, Runnable {}, "play", bg),
nextOrCustom = null,
prevOrCustom = null,
custom0 = MediaAction(icon, null, "custom 0", bg),
custom1 = MediaAction(icon, null, "custom 1", bg),
true,
false
)
val state = mediaData.copy(semanticActions = semanticActions)
player.attachPlayer(viewHolder)
player.bindPlayer(state, PACKAGE)
assertThat(actionPrev.isEnabled()).isFalse()
assertThat(actionPrev.drawable).isNull()
verify(expandedSet).setVisibility(R.id.actionPrev, ConstraintSet.GONE)
assertThat(actionNext.isEnabled()).isFalse()
assertThat(actionNext.drawable).isNull()
verify(expandedSet).setVisibility(R.id.actionNext, ConstraintSet.INVISIBLE)
}
@Test
fun bind_seekBarDisabled_seekBarVisibilityIsSetToInvisible() {
whenever(seekBarViewModel.getEnabled()).thenReturn(false)
......
......@@ -838,6 +838,9 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(actions.custom1).isNotNull()
assertThat(actions.custom1!!.contentDescription).isEqualTo(customDesc[1])
assertThat(actions.reserveNext).isTrue()
assertThat(actions.reservePrev).isTrue()
}
@Test
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment