Loading api/current.txt +3 −3 Original line number Diff line number Diff line Loading @@ -29086,12 +29086,12 @@ package android.view.accessibility { } public class CaptioningManager { method public void addCaptioningStateChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener); method public void addCaptioningChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener); method public final float getFontScale(); method public final java.util.Locale getLocale(); method public android.view.accessibility.CaptioningManager.CaptionStyle getUserStyle(); method public final boolean isEnabled(); method public void removeCaptioningStateChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener); method public void removeCaptioningChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener); } public static final class CaptioningManager.CaptionStyle { Loading @@ -29105,7 +29105,7 @@ package android.view.accessibility { field public final int foregroundColor; } public abstract class CaptioningManager.CaptioningChangeListener { public static abstract class CaptioningManager.CaptioningChangeListener { ctor public CaptioningManager.CaptioningChangeListener(); method public void onEnabledChanged(boolean); method public void onFontScaleChanged(float); core/java/android/view/accessibility/CaptioningManager.java +4 −4 Original line number Diff line number Diff line Loading @@ -140,7 +140,7 @@ public class CaptioningManager { * * @param listener the listener to add */ public void addCaptioningStateChangeListener(CaptioningChangeListener listener) { public void addCaptioningChangeListener(CaptioningChangeListener listener) { synchronized (mListeners) { if (mListeners.isEmpty()) { registerObserver(Secure.ACCESSIBILITY_CAPTIONING_ENABLED); Loading @@ -163,11 +163,11 @@ public class CaptioningManager { /** * Removes a listener previously added using * {@link #addCaptioningStateChangeListener}. * {@link #addCaptioningChangeListener}. * * @param listener the listener to remove */ public void removeCaptioningStateChangeListener(CaptioningChangeListener listener) { public void removeCaptioningChangeListener(CaptioningChangeListener listener) { synchronized (mListeners) { mListeners.remove(listener); Loading Loading @@ -366,7 +366,7 @@ public class CaptioningManager { * Listener for changes in captioning properties, including enabled state * and user style preferences. */ public abstract class CaptioningChangeListener { public static abstract class CaptioningChangeListener { /** * Called when the captioning enabled state changes. * Loading core/java/android/widget/VideoView.java +68 −94 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.media.MediaPlayer.OnErrorListener; import android.media.MediaPlayer.OnInfoListener; import android.media.Metadata; import android.media.SubtitleController; import android.media.SubtitleTrack.RenderingWidget; import android.media.WebVttRenderer; import android.net.Uri; import android.util.AttributeSet; Loading @@ -46,7 +47,6 @@ import android.widget.MediaController.MediaPlayerControl; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Map; import java.util.Vector; Loading Loading @@ -100,14 +100,11 @@ public class VideoView extends SurfaceView private boolean mCanSeekBack; private boolean mCanSeekForward; /** List of views overlaid on top of the video. */ private ArrayList<View> mOverlays; /** Subtitle rendering widget overlaid on top of the video. */ private RenderingWidget mSubtitleWidget; /** * Listener for overlay layout changes. Invalidates the video view to ensure * that captions are redrawn whenever their layout changes. */ private OnLayoutChangeListener mOverlayLayoutListener; /** Listener for changes to subtitle data, used to redraw when needed. */ private RenderingWidget.OnChangedListener mSubtitlesChangedListener; public VideoView(Context context) { super(context); Loading Loading @@ -302,11 +299,10 @@ public class VideoView extends SurfaceView mMediaPlayer = new MediaPlayer(); // TODO: create SubtitleController in MediaPlayer, but we need // a context for the subtitle renderers SubtitleController controller = new SubtitleController( getContext(), mMediaPlayer.getMediaTimeProvider(), mMediaPlayer); controller.registerRenderer(new WebVttRenderer(getContext(), null)); final Context context = getContext(); final SubtitleController controller = new SubtitleController( context, mMediaPlayer.getMediaTimeProvider(), mMediaPlayer); controller.registerRenderer(new WebVttRenderer(context)); mMediaPlayer.setSubtitleAnchor(controller, this); if (mAudioSession != 0) { Loading Loading @@ -792,117 +788,95 @@ public class VideoView extends SurfaceView } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); protected void onAttachedToWindow() { super.onAttachedToWindow(); // Layout overlay views, if necessary. if (changed && mOverlays != null && !mOverlays.isEmpty()) { measureAndLayoutOverlays(); if (mSubtitleWidget != null) { mSubtitleWidget.onAttachedToWindow(); } } @Override public void draw(Canvas canvas) { super.draw(canvas); protected void onDetachedFromWindow() { super.onDetachedFromWindow(); final int count = mOverlays.size(); for (int i = 0; i < count; i++) { final View overlay = mOverlays.get(i); overlay.draw(canvas); if (mSubtitleWidget != null) { mSubtitleWidget.onDetachedFromWindow(); } } /** * Adds a view to be overlaid on top of this video view. During layout, the * view will be forced to match the bounds, less padding, of the video view. * <p> * Overlays are drawn in the order they are added. The last added overlay * will be drawn on top. * * @param overlay the view to overlay * @see #removeOverlay(View) */ private void addOverlay(View overlay) { if (mOverlays == null) { mOverlays = new ArrayList<View>(1); } if (mOverlayLayoutListener == null) { mOverlayLayoutListener = new OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { invalidate(); } }; } if (mOverlays.isEmpty()) { setWillNotDraw(false); } protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); mOverlays.add(overlay); overlay.addOnLayoutChangeListener(mOverlayLayoutListener); measureAndLayoutOverlays(); if (mSubtitleWidget != null) { measureAndLayoutSubtitleWidget(); } /** * Removes a view previously added using {@link #addOverlay}. * * @param overlay the view to remove * @see #addOverlay(View) */ private void removeOverlay(View overlay) { if (mOverlays == null) { return; } overlay.removeOnLayoutChangeListener(mOverlayLayoutListener); mOverlays.remove(overlay); @Override public void draw(Canvas canvas) { super.draw(canvas); if (mOverlays.isEmpty()) { setWillNotDraw(true); if (mSubtitleWidget != null) { final int saveCount = canvas.save(); canvas.translate(getPaddingLeft(), getPaddingTop()); mSubtitleWidget.draw(canvas); canvas.restoreToCount(saveCount); } invalidate(); } /** * Forces a measurement and layout pass for all overlaid views. * * @see #addOverlay(View) * @see #setSubtitleWidget(RenderingWidget) */ private void measureAndLayoutOverlays() { final int left = getPaddingLeft(); final int top = getPaddingTop(); final int right = getWidth() - left - getPaddingRight(); final int bottom = getHeight() - top - getPaddingBottom(); final int widthSpec = MeasureSpec.makeMeasureSpec(right - left, MeasureSpec.EXACTLY); final int heightSpec = MeasureSpec.makeMeasureSpec(bottom - top, MeasureSpec.EXACTLY); private void measureAndLayoutSubtitleWidget() { final int width = getWidth() - getPaddingLeft() - getPaddingRight(); final int height = getHeight() - getPaddingTop() - getPaddingBottom(); final int count = mOverlays.size(); for (int i = 0; i < count; i++) { final View overlay = mOverlays.get(i); overlay.measure(widthSpec, heightSpec); overlay.layout(left, top, right, bottom); } mSubtitleWidget.setSize(width, height); } /** @hide */ @Override public void setSubtitleView(View view) { if (mSubtitleView == view) { public void setSubtitleWidget(RenderingWidget subtitleWidget) { if (mSubtitleWidget == subtitleWidget) { return; } if (mSubtitleView != null) { removeOverlay(mSubtitleView); final boolean attachedToWindow = isAttachedToWindow(); if (mSubtitleWidget != null) { if (attachedToWindow) { mSubtitleWidget.onDetachedFromWindow(); } mSubtitleWidget.setOnChangedListener(null); } mSubtitleWidget = subtitleWidget; if (subtitleWidget != null) { if (mSubtitlesChangedListener == null) { mSubtitlesChangedListener = new RenderingWidget.OnChangedListener() { @Override public void onChanged(RenderingWidget renderingWidget) { invalidate(); } }; } mSubtitleView = view; if (mSubtitleView != null) { addOverlay(mSubtitleView); setWillNotDraw(false); subtitleWidget.setOnChangedListener(mSubtitlesChangedListener); if (attachedToWindow) { subtitleWidget.onAttachedToWindow(); requestLayout(); } } else { setWillNotDraw(true); } private View mSubtitleView; invalidate(); } } core/java/com/android/internal/widget/SubtitleView.java +4 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,10 @@ public class SubtitleView extends View { private float mSpacingAdd = 0; private int mInnerPaddingX = 0; public SubtitleView(Context context) { this(context, null); } public SubtitleView(Context context, AttributeSet attrs) { this(context, attrs, 0); } Loading media/java/android/media/SubtitleController.java +11 −15 Original line number Diff line number Diff line Loading @@ -20,8 +20,7 @@ import java.util.Locale; import java.util.Vector; import android.content.Context; import android.media.MediaPlayer.OnSubtitleDataListener; import android.view.View; import android.media.SubtitleTrack.RenderingWidget; import android.view.accessibility.CaptioningManager; /** Loading @@ -32,7 +31,6 @@ import android.view.accessibility.CaptioningManager; * @hide */ public class SubtitleController { private Context mContext; private MediaTimeProvider mTimeProvider; private Vector<Renderer> mRenderers; private Vector<SubtitleTrack> mTracks; Loading @@ -50,7 +48,6 @@ public class SubtitleController { Context context, MediaTimeProvider timeProvider, Listener listener) { mContext = context; mTimeProvider = timeProvider; mListener = listener; Loading Loading @@ -79,11 +76,11 @@ public class SubtitleController { return mSelectedTrack; } private View getSubtitleView() { private RenderingWidget getRenderingWidget() { if (mSelectedTrack == null) { return null; } return mSelectedTrack.getView(); return mSelectedTrack.getRenderingWidget(); } /** Loading @@ -110,7 +107,7 @@ public class SubtitleController { } mSelectedTrack = track; mAnchor.setSubtitleView(getSubtitleView()); mAnchor.setSubtitleWidget(getRenderingWidget()); if (mSelectedTrack != null) { mSelectedTrack.setTimeProvider(mTimeProvider); Loading Loading @@ -268,17 +265,16 @@ public class SubtitleController { } /** * Subtitle anchor, an object that is able to display a subtitle view, * Subtitle anchor, an object that is able to display a subtitle renderer, * e.g. a VideoView. */ public interface Anchor { /** * Anchor should set the subtitle view to the supplied view, * or none, if the supplied view is null. * * @param view subtitle view, or null * Anchor should use the supplied subtitle rendering widget, or * none if it is null. * @hide */ public void setSubtitleView(View view); public void setSubtitleWidget(RenderingWidget subtitleWidget); } private Anchor mAnchor; Loading @@ -290,11 +286,11 @@ public class SubtitleController { } if (mAnchor != null) { mAnchor.setSubtitleView(null); mAnchor.setSubtitleWidget(null); } mAnchor = anchor; if (mAnchor != null) { mAnchor.setSubtitleView(getSubtitleView()); mAnchor.setSubtitleWidget(getRenderingWidget()); } } Loading Loading
api/current.txt +3 −3 Original line number Diff line number Diff line Loading @@ -29086,12 +29086,12 @@ package android.view.accessibility { } public class CaptioningManager { method public void addCaptioningStateChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener); method public void addCaptioningChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener); method public final float getFontScale(); method public final java.util.Locale getLocale(); method public android.view.accessibility.CaptioningManager.CaptionStyle getUserStyle(); method public final boolean isEnabled(); method public void removeCaptioningStateChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener); method public void removeCaptioningChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener); } public static final class CaptioningManager.CaptionStyle { Loading @@ -29105,7 +29105,7 @@ package android.view.accessibility { field public final int foregroundColor; } public abstract class CaptioningManager.CaptioningChangeListener { public static abstract class CaptioningManager.CaptioningChangeListener { ctor public CaptioningManager.CaptioningChangeListener(); method public void onEnabledChanged(boolean); method public void onFontScaleChanged(float);
core/java/android/view/accessibility/CaptioningManager.java +4 −4 Original line number Diff line number Diff line Loading @@ -140,7 +140,7 @@ public class CaptioningManager { * * @param listener the listener to add */ public void addCaptioningStateChangeListener(CaptioningChangeListener listener) { public void addCaptioningChangeListener(CaptioningChangeListener listener) { synchronized (mListeners) { if (mListeners.isEmpty()) { registerObserver(Secure.ACCESSIBILITY_CAPTIONING_ENABLED); Loading @@ -163,11 +163,11 @@ public class CaptioningManager { /** * Removes a listener previously added using * {@link #addCaptioningStateChangeListener}. * {@link #addCaptioningChangeListener}. * * @param listener the listener to remove */ public void removeCaptioningStateChangeListener(CaptioningChangeListener listener) { public void removeCaptioningChangeListener(CaptioningChangeListener listener) { synchronized (mListeners) { mListeners.remove(listener); Loading Loading @@ -366,7 +366,7 @@ public class CaptioningManager { * Listener for changes in captioning properties, including enabled state * and user style preferences. */ public abstract class CaptioningChangeListener { public static abstract class CaptioningChangeListener { /** * Called when the captioning enabled state changes. * Loading
core/java/android/widget/VideoView.java +68 −94 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.media.MediaPlayer.OnErrorListener; import android.media.MediaPlayer.OnInfoListener; import android.media.Metadata; import android.media.SubtitleController; import android.media.SubtitleTrack.RenderingWidget; import android.media.WebVttRenderer; import android.net.Uri; import android.util.AttributeSet; Loading @@ -46,7 +47,6 @@ import android.widget.MediaController.MediaPlayerControl; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Map; import java.util.Vector; Loading Loading @@ -100,14 +100,11 @@ public class VideoView extends SurfaceView private boolean mCanSeekBack; private boolean mCanSeekForward; /** List of views overlaid on top of the video. */ private ArrayList<View> mOverlays; /** Subtitle rendering widget overlaid on top of the video. */ private RenderingWidget mSubtitleWidget; /** * Listener for overlay layout changes. Invalidates the video view to ensure * that captions are redrawn whenever their layout changes. */ private OnLayoutChangeListener mOverlayLayoutListener; /** Listener for changes to subtitle data, used to redraw when needed. */ private RenderingWidget.OnChangedListener mSubtitlesChangedListener; public VideoView(Context context) { super(context); Loading Loading @@ -302,11 +299,10 @@ public class VideoView extends SurfaceView mMediaPlayer = new MediaPlayer(); // TODO: create SubtitleController in MediaPlayer, but we need // a context for the subtitle renderers SubtitleController controller = new SubtitleController( getContext(), mMediaPlayer.getMediaTimeProvider(), mMediaPlayer); controller.registerRenderer(new WebVttRenderer(getContext(), null)); final Context context = getContext(); final SubtitleController controller = new SubtitleController( context, mMediaPlayer.getMediaTimeProvider(), mMediaPlayer); controller.registerRenderer(new WebVttRenderer(context)); mMediaPlayer.setSubtitleAnchor(controller, this); if (mAudioSession != 0) { Loading Loading @@ -792,117 +788,95 @@ public class VideoView extends SurfaceView } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); protected void onAttachedToWindow() { super.onAttachedToWindow(); // Layout overlay views, if necessary. if (changed && mOverlays != null && !mOverlays.isEmpty()) { measureAndLayoutOverlays(); if (mSubtitleWidget != null) { mSubtitleWidget.onAttachedToWindow(); } } @Override public void draw(Canvas canvas) { super.draw(canvas); protected void onDetachedFromWindow() { super.onDetachedFromWindow(); final int count = mOverlays.size(); for (int i = 0; i < count; i++) { final View overlay = mOverlays.get(i); overlay.draw(canvas); if (mSubtitleWidget != null) { mSubtitleWidget.onDetachedFromWindow(); } } /** * Adds a view to be overlaid on top of this video view. During layout, the * view will be forced to match the bounds, less padding, of the video view. * <p> * Overlays are drawn in the order they are added. The last added overlay * will be drawn on top. * * @param overlay the view to overlay * @see #removeOverlay(View) */ private void addOverlay(View overlay) { if (mOverlays == null) { mOverlays = new ArrayList<View>(1); } if (mOverlayLayoutListener == null) { mOverlayLayoutListener = new OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { invalidate(); } }; } if (mOverlays.isEmpty()) { setWillNotDraw(false); } protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); mOverlays.add(overlay); overlay.addOnLayoutChangeListener(mOverlayLayoutListener); measureAndLayoutOverlays(); if (mSubtitleWidget != null) { measureAndLayoutSubtitleWidget(); } /** * Removes a view previously added using {@link #addOverlay}. * * @param overlay the view to remove * @see #addOverlay(View) */ private void removeOverlay(View overlay) { if (mOverlays == null) { return; } overlay.removeOnLayoutChangeListener(mOverlayLayoutListener); mOverlays.remove(overlay); @Override public void draw(Canvas canvas) { super.draw(canvas); if (mOverlays.isEmpty()) { setWillNotDraw(true); if (mSubtitleWidget != null) { final int saveCount = canvas.save(); canvas.translate(getPaddingLeft(), getPaddingTop()); mSubtitleWidget.draw(canvas); canvas.restoreToCount(saveCount); } invalidate(); } /** * Forces a measurement and layout pass for all overlaid views. * * @see #addOverlay(View) * @see #setSubtitleWidget(RenderingWidget) */ private void measureAndLayoutOverlays() { final int left = getPaddingLeft(); final int top = getPaddingTop(); final int right = getWidth() - left - getPaddingRight(); final int bottom = getHeight() - top - getPaddingBottom(); final int widthSpec = MeasureSpec.makeMeasureSpec(right - left, MeasureSpec.EXACTLY); final int heightSpec = MeasureSpec.makeMeasureSpec(bottom - top, MeasureSpec.EXACTLY); private void measureAndLayoutSubtitleWidget() { final int width = getWidth() - getPaddingLeft() - getPaddingRight(); final int height = getHeight() - getPaddingTop() - getPaddingBottom(); final int count = mOverlays.size(); for (int i = 0; i < count; i++) { final View overlay = mOverlays.get(i); overlay.measure(widthSpec, heightSpec); overlay.layout(left, top, right, bottom); } mSubtitleWidget.setSize(width, height); } /** @hide */ @Override public void setSubtitleView(View view) { if (mSubtitleView == view) { public void setSubtitleWidget(RenderingWidget subtitleWidget) { if (mSubtitleWidget == subtitleWidget) { return; } if (mSubtitleView != null) { removeOverlay(mSubtitleView); final boolean attachedToWindow = isAttachedToWindow(); if (mSubtitleWidget != null) { if (attachedToWindow) { mSubtitleWidget.onDetachedFromWindow(); } mSubtitleWidget.setOnChangedListener(null); } mSubtitleWidget = subtitleWidget; if (subtitleWidget != null) { if (mSubtitlesChangedListener == null) { mSubtitlesChangedListener = new RenderingWidget.OnChangedListener() { @Override public void onChanged(RenderingWidget renderingWidget) { invalidate(); } }; } mSubtitleView = view; if (mSubtitleView != null) { addOverlay(mSubtitleView); setWillNotDraw(false); subtitleWidget.setOnChangedListener(mSubtitlesChangedListener); if (attachedToWindow) { subtitleWidget.onAttachedToWindow(); requestLayout(); } } else { setWillNotDraw(true); } private View mSubtitleView; invalidate(); } }
core/java/com/android/internal/widget/SubtitleView.java +4 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,10 @@ public class SubtitleView extends View { private float mSpacingAdd = 0; private int mInnerPaddingX = 0; public SubtitleView(Context context) { this(context, null); } public SubtitleView(Context context, AttributeSet attrs) { this(context, attrs, 0); } Loading
media/java/android/media/SubtitleController.java +11 −15 Original line number Diff line number Diff line Loading @@ -20,8 +20,7 @@ import java.util.Locale; import java.util.Vector; import android.content.Context; import android.media.MediaPlayer.OnSubtitleDataListener; import android.view.View; import android.media.SubtitleTrack.RenderingWidget; import android.view.accessibility.CaptioningManager; /** Loading @@ -32,7 +31,6 @@ import android.view.accessibility.CaptioningManager; * @hide */ public class SubtitleController { private Context mContext; private MediaTimeProvider mTimeProvider; private Vector<Renderer> mRenderers; private Vector<SubtitleTrack> mTracks; Loading @@ -50,7 +48,6 @@ public class SubtitleController { Context context, MediaTimeProvider timeProvider, Listener listener) { mContext = context; mTimeProvider = timeProvider; mListener = listener; Loading Loading @@ -79,11 +76,11 @@ public class SubtitleController { return mSelectedTrack; } private View getSubtitleView() { private RenderingWidget getRenderingWidget() { if (mSelectedTrack == null) { return null; } return mSelectedTrack.getView(); return mSelectedTrack.getRenderingWidget(); } /** Loading @@ -110,7 +107,7 @@ public class SubtitleController { } mSelectedTrack = track; mAnchor.setSubtitleView(getSubtitleView()); mAnchor.setSubtitleWidget(getRenderingWidget()); if (mSelectedTrack != null) { mSelectedTrack.setTimeProvider(mTimeProvider); Loading Loading @@ -268,17 +265,16 @@ public class SubtitleController { } /** * Subtitle anchor, an object that is able to display a subtitle view, * Subtitle anchor, an object that is able to display a subtitle renderer, * e.g. a VideoView. */ public interface Anchor { /** * Anchor should set the subtitle view to the supplied view, * or none, if the supplied view is null. * * @param view subtitle view, or null * Anchor should use the supplied subtitle rendering widget, or * none if it is null. * @hide */ public void setSubtitleView(View view); public void setSubtitleWidget(RenderingWidget subtitleWidget); } private Anchor mAnchor; Loading @@ -290,11 +286,11 @@ public class SubtitleController { } if (mAnchor != null) { mAnchor.setSubtitleView(null); mAnchor.setSubtitleWidget(null); } mAnchor = anchor; if (mAnchor != null) { mAnchor.setSubtitleView(getSubtitleView()); mAnchor.setSubtitleWidget(getRenderingWidget()); } } Loading