Fix some PlayerControlView accessibility issues
- Fix focus when pausing and resuming - Prevent repeated readout of the playback position when paused #exofixit #minor-release Issue #9111 PiperOrigin-RevId: 395301765
This commit is contained in:
parent
e53e59388f
commit
86f8c4e44e
@ -37,6 +37,8 @@
|
||||
* Use `defStyleAttr` when obtaining styled attributes in
|
||||
`StyledPlayerView`, `PlayerView` and `PlayerControlView`
|
||||
([#9024](https://github.com/google/ExoPlayer/issues/9024)).
|
||||
* Fix accessibility focus in `PlayerControlView`
|
||||
([#9111](https://github.com/google/ExoPlayer/issues/9111)).
|
||||
* Remove deprecated symbols:
|
||||
* Remove `Renderer.VIDEO_SCALING_MODE_*` constants. Use identically named
|
||||
constants in `C` instead.
|
||||
|
@ -512,6 +512,9 @@ public class DefaultTimeBar extends View implements TimeBar {
|
||||
|
||||
@Override
|
||||
public void setPosition(long position) {
|
||||
if (this.position == position) {
|
||||
return;
|
||||
}
|
||||
this.position = position;
|
||||
setContentDescription(getProgressText());
|
||||
update();
|
||||
@ -519,12 +522,18 @@ public class DefaultTimeBar extends View implements TimeBar {
|
||||
|
||||
@Override
|
||||
public void setBufferedPosition(long bufferedPosition) {
|
||||
if (this.bufferedPosition == bufferedPosition) {
|
||||
return;
|
||||
}
|
||||
this.bufferedPosition = bufferedPosition;
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDuration(long duration) {
|
||||
if (this.duration == duration) {
|
||||
return;
|
||||
}
|
||||
this.duration = duration;
|
||||
if (scrubbing && duration == C.TIME_UNSET) {
|
||||
stopScrubbing(/* canceled= */ true);
|
||||
|
@ -41,10 +41,13 @@ import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.DoNotInline;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ControlDispatcher;
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
@ -339,6 +342,8 @@ public class PlayerControlView extends FrameLayout {
|
||||
private long[] extraAdGroupTimesMs;
|
||||
private boolean[] extraPlayedAdGroups;
|
||||
private long currentWindowOffset;
|
||||
private long currentPosition;
|
||||
private long currentBufferedPosition;
|
||||
|
||||
public PlayerControlView(Context context) {
|
||||
this(context, /* attrs= */ null);
|
||||
@ -783,6 +788,7 @@ public class PlayerControlView extends FrameLayout {
|
||||
}
|
||||
updateAll();
|
||||
requestPlayPauseFocus();
|
||||
requestPlayPauseAccessibilityFocus();
|
||||
}
|
||||
// Call hideAfterTimeout even if already visible to reset the timeout.
|
||||
hideAfterTimeout();
|
||||
@ -831,18 +837,30 @@ public class PlayerControlView extends FrameLayout {
|
||||
return;
|
||||
}
|
||||
boolean requestPlayPauseFocus = false;
|
||||
boolean requestPlayPauseAccessibilityFocus = false;
|
||||
boolean shouldShowPauseButton = shouldShowPauseButton();
|
||||
if (playButton != null) {
|
||||
requestPlayPauseFocus |= shouldShowPauseButton && playButton.isFocused();
|
||||
requestPlayPauseAccessibilityFocus |=
|
||||
Util.SDK_INT < 21
|
||||
? requestPlayPauseFocus
|
||||
: (shouldShowPauseButton && Api21.isAccessibilityFocused(playButton));
|
||||
playButton.setVisibility(shouldShowPauseButton ? GONE : VISIBLE);
|
||||
}
|
||||
if (pauseButton != null) {
|
||||
requestPlayPauseFocus |= !shouldShowPauseButton && pauseButton.isFocused();
|
||||
requestPlayPauseAccessibilityFocus |=
|
||||
Util.SDK_INT < 21
|
||||
? requestPlayPauseFocus
|
||||
: (!shouldShowPauseButton && Api21.isAccessibilityFocused(pauseButton));
|
||||
pauseButton.setVisibility(shouldShowPauseButton ? VISIBLE : GONE);
|
||||
}
|
||||
if (requestPlayPauseFocus) {
|
||||
requestPlayPauseFocus();
|
||||
}
|
||||
if (requestPlayPauseAccessibilityFocus) {
|
||||
requestPlayPauseAccessibilityFocus();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNavigation() {
|
||||
@ -1021,14 +1039,21 @@ public class PlayerControlView extends FrameLayout {
|
||||
position = currentWindowOffset + player.getContentPosition();
|
||||
bufferedPosition = currentWindowOffset + player.getContentBufferedPosition();
|
||||
}
|
||||
if (positionView != null && !scrubbing) {
|
||||
boolean positionChanged = position != currentPosition;
|
||||
boolean bufferedPositionChanged = bufferedPosition != currentBufferedPosition;
|
||||
currentPosition = position;
|
||||
currentBufferedPosition = bufferedPosition;
|
||||
|
||||
// Only update the TextView if the position has changed, else TalkBack will repeatedly read the
|
||||
// same position to the user.
|
||||
if (positionView != null && !scrubbing && positionChanged) {
|
||||
positionView.setText(Util.getStringForTime(formatBuilder, formatter, position));
|
||||
}
|
||||
if (timeBar != null) {
|
||||
timeBar.setPosition(position);
|
||||
timeBar.setBufferedPosition(bufferedPosition);
|
||||
}
|
||||
if (progressUpdateListener != null) {
|
||||
if (progressUpdateListener != null && (positionChanged || bufferedPositionChanged)) {
|
||||
progressUpdateListener.onProgressUpdate(position, bufferedPosition);
|
||||
}
|
||||
|
||||
@ -1065,6 +1090,15 @@ public class PlayerControlView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private void requestPlayPauseAccessibilityFocus() {
|
||||
boolean shouldShowPauseButton = shouldShowPauseButton();
|
||||
if (!shouldShowPauseButton && playButton != null) {
|
||||
playButton.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
|
||||
} else if (shouldShowPauseButton && pauseButton != null) {
|
||||
pauseButton.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateButton(boolean visible, boolean enabled, @Nullable View view) {
|
||||
if (view == null) {
|
||||
return;
|
||||
@ -1339,4 +1373,12 @@ public class PlayerControlView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(21)
|
||||
private static final class Api21 {
|
||||
@DoNotInline
|
||||
public static boolean isAccessibilityFocused(View view) {
|
||||
return view.isAccessibilityFocused();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user