103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar/*
203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * Copyright (C) 2013 The Android Open Source Project
303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar *
403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * you may not use this file except in compliance with the License.
603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * You may obtain a copy of the License at
703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar *
803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar *      http://www.apache.org/licenses/LICENSE-2.0
903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar *
1003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * Unless required by applicable law or agreed to in writing, software
1103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
1203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * See the License for the specific language governing permissions and
1403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * limitations under the License.
1503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar */
1603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
1703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnarpackage android.media;
1803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
1903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnarimport java.util.Locale;
2003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnarimport java.util.Vector;
2103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
2203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnarimport android.content.Context;
23a460ea1a2c178a2c1816b1a983333166726ad579Robert Shihimport android.media.MediaPlayer.TrackInfo;
24d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viveretteimport android.media.SubtitleTrack.RenderingWidget;
2529f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnarimport android.os.Handler;
2629f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnarimport android.os.Looper;
2729f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnarimport android.os.Message;
2803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnarimport android.view.accessibility.CaptioningManager;
2903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
3003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar/**
3103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * The subtitle controller provides the architecture to display subtitles for a
3203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * media source.  It allows specifying which tracks to display, on which anchor
3303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * to display them, and also allows adding external, out-of-band subtitle tracks.
3403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar *
3503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar * @hide
3603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar */
3703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnarpublic class SubtitleController {
3803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    private MediaTimeProvider mTimeProvider;
3903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    private Vector<Renderer> mRenderers;
4003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    private Vector<SubtitleTrack> mTracks;
4103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    private SubtitleTrack mSelectedTrack;
4203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    private boolean mShowing;
4387399fc21b642688a690be5869f14a7ba020afdbLajos Molnar    private CaptioningManager mCaptioningManager;
4429f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private Handler mHandler;
4529f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar
4629f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private static final int WHAT_SHOW = 1;
4729f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private static final int WHAT_HIDE = 2;
4829f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private static final int WHAT_SELECT_TRACK = 3;
4929f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private static final int WHAT_SELECT_DEFAULT_TRACK = 4;
5029f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar
5129f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private final Handler.Callback mCallback = new Handler.Callback() {
5229f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        @Override
5329f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        public boolean handleMessage(Message msg) {
5429f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            switch (msg.what) {
5529f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            case WHAT_SHOW:
5629f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar                doShow();
5729f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar                return true;
5829f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            case WHAT_HIDE:
5929f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar                doHide();
6029f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar                return true;
6129f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            case WHAT_SELECT_TRACK:
6229f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar                doSelectTrack((SubtitleTrack)msg.obj);
6329f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar                return true;
6429f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            case WHAT_SELECT_DEFAULT_TRACK:
6529f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar                doSelectDefaultTrack();
6629f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar                return true;
6729f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            default:
6829f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar                return false;
6929f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            }
7029f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        }
7129f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    };
7203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
73d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar    private CaptioningManager.CaptioningChangeListener mCaptioningChangeListener =
74d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        new CaptioningManager.CaptioningChangeListener() {
75d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            /** @hide */
76d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            @Override
77d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            public void onEnabledChanged(boolean enabled) {
78d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                selectDefaultTrack();
79d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            }
80d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar
81d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            /** @hide */
82d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            @Override
83d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            public void onLocaleChanged(Locale locale) {
84d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                selectDefaultTrack();
85d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            }
86d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        };
87d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar
8803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    /**
8903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * Creates a subtitle controller for a media playback object that implements
9003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * the MediaTimeProvider interface.
9103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     *
9203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * @param timeProvider
9303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     */
9403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public SubtitleController(
9503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            Context context,
9603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            MediaTimeProvider timeProvider,
9703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            Listener listener) {
9803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mTimeProvider = timeProvider;
9903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mListener = listener;
10003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
10103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mRenderers = new Vector<Renderer>();
10203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mShowing = false;
10303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mTracks = new Vector<SubtitleTrack>();
10487399fc21b642688a690be5869f14a7ba020afdbLajos Molnar        mCaptioningManager =
10587399fc21b642688a690be5869f14a7ba020afdbLajos Molnar            (CaptioningManager)context.getSystemService(Context.CAPTIONING_SERVICE);
10603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
10703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
108d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar    @Override
109d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar    protected void finalize() throws Throwable {
110d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        mCaptioningManager.removeCaptioningChangeListener(
111d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                mCaptioningChangeListener);
112d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        super.finalize();
113d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar    }
114d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar
11503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    /**
11603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * @return the available subtitle tracks for this media. These include
11703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * the tracks found by {@link MediaPlayer} as well as any tracks added
11803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * manually via {@link #addTrack}.
11903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     */
12003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public SubtitleTrack[] getTracks() {
121d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        synchronized(mTracks) {
122d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            SubtitleTrack[] tracks = new SubtitleTrack[mTracks.size()];
123d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            mTracks.toArray(tracks);
124d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            return tracks;
125d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        }
12603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
12703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
12803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    /**
12903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * @return the currently selected subtitle track
13003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     */
13103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public SubtitleTrack getSelectedTrack() {
13203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        return mSelectedTrack;
13303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
13403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
135d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette    private RenderingWidget getRenderingWidget() {
13603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (mSelectedTrack == null) {
13703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            return null;
13803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
139d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette        return mSelectedTrack.getRenderingWidget();
14003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
14103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
14203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    /**
14303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * Selects a subtitle track.  As a result, this track will receive
14403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * in-band data from the {@link MediaPlayer}.  However, this does
14503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * not change the subtitle visibility.
14603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     *
14729f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
148d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *
14903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * @param track The subtitle track to select.  This must be one of the
15003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     *              tracks in {@link #getTracks}.
15103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * @return true if the track was successfully selected.
15203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     */
15303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public boolean selectTrack(SubtitleTrack track) {
15403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (track != null && !mTracks.contains(track)) {
15503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            return false;
15603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
15729f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar
15829f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_TRACK, track));
15929f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        return true;
16029f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    }
16129f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar
16229f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private void doSelectTrack(SubtitleTrack track) {
16303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mTrackIsExplicit = true;
16403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (mSelectedTrack == track) {
16529f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            return;
16603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
16703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
16803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (mSelectedTrack != null) {
16903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            mSelectedTrack.hide();
17003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            mSelectedTrack.setTimeProvider(null);
17103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
17203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
17303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mSelectedTrack = track;
174d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        if (mAnchor != null) {
175d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            mAnchor.setSubtitleWidget(getRenderingWidget());
176d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        }
17703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
17803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (mSelectedTrack != null) {
17903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            mSelectedTrack.setTimeProvider(mTimeProvider);
18003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            mSelectedTrack.show();
18103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
18203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
18303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (mListener != null) {
18403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            mListener.onSubtitleTrackSelected(track);
18503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
18603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
18703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
18803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    /**
18903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * @return the default subtitle track based on system preferences, or null,
19003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * if no such track exists in this manager.
191d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *
192d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     * Supports HLS-flags: AUTOSELECT, FORCED & DEFAULT.
193d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *
194d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     * 1. If captioning is disabled, only consider FORCED tracks. Otherwise,
195d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     * consider all tracks, but prefer non-FORCED ones.
196d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     * 2. If user selected "Default" caption language:
197d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *   a. If there is a considered track with DEFAULT=yes, returns that track
198d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *      (favor the first one in the current language if there are more than
199d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *      one default tracks, or the first in general if none of them are in
200d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *      the current language).
201d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *   b. Otherwise, if there is a track with AUTOSELECT=yes in the current
202d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *      language, return that one.
203d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *   c. If there are no default tracks, and no autoselectable tracks in the
204d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *      current language, return null.
205d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     * 3. If there is a track with the caption language, select that one.  Prefer
206d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     * the one with AUTOSELECT=no.
207d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *
208d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     * The default values for these flags are DEFAULT=no, AUTOSELECT=yes
209d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     * and FORCED=no.
21003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     */
21103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public SubtitleTrack getDefaultTrack() {
212d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        SubtitleTrack bestTrack = null;
213d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        int bestScore = -1;
214d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar
215d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        Locale selectedLocale = mCaptioningManager.getLocale();
216d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        Locale locale = selectedLocale;
217d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        if (locale == null) {
218d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            locale = Locale.getDefault();
219d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        }
220d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        boolean selectForced = !mCaptioningManager.isEnabled();
221d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar
222d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        synchronized(mTracks) {
223d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            for (SubtitleTrack track: mTracks) {
224d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                MediaFormat format = track.getFormat();
225d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                String language = format.getString(MediaFormat.KEY_LANGUAGE);
226d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                boolean forced =
227d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    format.getInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0;
228d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                boolean autoselect =
229d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    format.getInteger(MediaFormat.KEY_IS_AUTOSELECT, 1) != 0;
230d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                boolean is_default =
231d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    format.getInteger(MediaFormat.KEY_IS_DEFAULT, 0) != 0;
232d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar
233d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                boolean languageMatches =
234d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    (locale == null ||
235d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    locale.getLanguage().equals("") ||
236d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    locale.getISO3Language().equals(language) ||
237d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    locale.getLanguage().equals(language));
238d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                // is_default is meaningless unless caption language is 'default'
239d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                int score = (forced ? 0 : 8) +
240d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    (((selectedLocale == null) && is_default) ? 4 : 0) +
241d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    (autoselect ? 0 : 2) + (languageMatches ? 1 : 0);
242d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar
243d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                if (selectForced && !forced) {
244d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    continue;
245d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                }
246d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar
247d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                // we treat null locale/language as matching any language
248d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                if ((selectedLocale == null && is_default) ||
249d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    (languageMatches &&
250d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                     (autoselect || forced || selectedLocale != null))) {
251d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    if (score > bestScore) {
252d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                        bestScore = score;
253d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                        bestTrack = track;
254d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    }
255d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                }
25603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            }
25703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
258d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        return bestTrack;
25903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
26003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
26103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    private boolean mTrackIsExplicit = false;
26203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    private boolean mVisibilityIsExplicit = false;
26303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
26429f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    /** @hide - should be called from anchor thread */
26503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public void selectDefaultTrack() {
26629f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_DEFAULT_TRACK));
26729f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    }
26829f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar
26929f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private void doSelectDefaultTrack() {
27003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (mTrackIsExplicit) {
271d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            // If track selection is explicit, but visibility
272d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            // is not, it falls back to the captioning setting
273d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            if (!mVisibilityIsExplicit) {
274d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                if (mCaptioningManager.isEnabled() ||
275d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    (mSelectedTrack != null &&
276d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                     mSelectedTrack.getFormat().getInteger(
277d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                            MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0)) {
278d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    show();
279a460ea1a2c178a2c1816b1a983333166726ad579Robert Shih                } else if (mSelectedTrack != null
280a460ea1a2c178a2c1816b1a983333166726ad579Robert Shih                        && mSelectedTrack.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
281d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    hide();
282d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                }
283d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                mVisibilityIsExplicit = false;
284d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            }
28503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            return;
28603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
28703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
288d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        // We can have a default (forced) track even if captioning
289d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        // is not enabled.  This is handled by getDefaultTrack().
290d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        // Show this track unless subtitles were explicitly hidden.
29103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        SubtitleTrack track = getDefaultTrack();
29203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (track != null) {
29303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            selectTrack(track);
29403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            mTrackIsExplicit = false;
29503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            if (!mVisibilityIsExplicit) {
296d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                show();
29703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar                mVisibilityIsExplicit = false;
29803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            }
29903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
30003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
30103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
30229f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    /** @hide - must be called from anchor thread */
30303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public void reset() {
30429f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        checkAnchorLooper();
30503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        hide();
30603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        selectTrack(null);
30703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mTracks.clear();
30803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mTrackIsExplicit = false;
30903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mVisibilityIsExplicit = false;
310d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        mCaptioningManager.removeCaptioningChangeListener(
311d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                mCaptioningChangeListener);
31203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
31303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
31403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    /**
31503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * Adds a new, external subtitle track to the manager.
31603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     *
31703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * @param format the format of the track that will include at least
31803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     *               the MIME type {@link MediaFormat@KEY_MIME}.
31903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * @return the created {@link SubtitleTrack} object
32003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     */
32103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public SubtitleTrack addTrack(MediaFormat format) {
322d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        synchronized(mRenderers) {
323d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            for (Renderer renderer: mRenderers) {
324d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                if (renderer.supports(format)) {
325d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    SubtitleTrack track = renderer.createTrack(format);
326d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    if (track != null) {
327d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                        synchronized(mTracks) {
328d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                            if (mTracks.size() == 0) {
329d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                                mCaptioningManager.addCaptioningChangeListener(
330d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                                        mCaptioningChangeListener);
331d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                            }
332d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                            mTracks.add(track);
333d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                        }
334d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                        return track;
335d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                    }
33603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar                }
33703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            }
33803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
33903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        return null;
34003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
34103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
34203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    /**
34303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * Show the selected (or default) subtitle track.
344d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *
34529f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
34603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     */
34703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public void show() {
34829f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        processOnAnchor(mHandler.obtainMessage(WHAT_SHOW));
34929f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    }
35029f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar
35129f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private void doShow() {
35203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mShowing = true;
35303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mVisibilityIsExplicit = true;
35403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (mSelectedTrack != null) {
35503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            mSelectedTrack.show();
35603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
35703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
35803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
35903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    /**
36003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * Hide the selected (or default) subtitle track.
361d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar     *
36229f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
36303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     */
36403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public void hide() {
36529f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        processOnAnchor(mHandler.obtainMessage(WHAT_HIDE));
36629f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    }
36729f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar
36829f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private void doHide() {
36903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mVisibilityIsExplicit = true;
37003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (mSelectedTrack != null) {
37103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            mSelectedTrack.hide();
37203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
37303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mShowing = false;
37403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
37503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
37603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    /**
37703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * Interface for supporting a single or multiple subtitle types in {@link
37803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * MediaPlayer}.
37903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     */
38003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public abstract static class Renderer {
38103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        /**
38203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * Called by {@link MediaPlayer}'s {@link SubtitleController} when a new
38303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * subtitle track is detected, to see if it should use this object to
38403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * parse and display this subtitle track.
38503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         *
38603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * @param format the format of the track that will include at least
38703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         *               the MIME type {@link MediaFormat@KEY_MIME}.
38803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         *
38903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * @return true if and only if the track format is supported by this
39003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * renderer
39103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         */
39203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        public abstract boolean supports(MediaFormat format);
39303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
39403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        /**
39503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * Called by {@link MediaPlayer}'s {@link SubtitleController} for each
39603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * subtitle track that was detected and is supported by this object to
39703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * create a {@link SubtitleTrack} object.  This object will be created
39803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * for each track that was found.  If the track is selected for display,
39903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * this object will be used to parse and display the track data.
40003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         *
40103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * @param format the format of the track that will include at least
40203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         *               the MIME type {@link MediaFormat@KEY_MIME}.
40303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * @return a {@link SubtitleTrack} object that will be used to parse
40403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * and render the subtitle track.
40503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         */
40603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        public abstract SubtitleTrack createTrack(MediaFormat format);
40703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
40803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
40903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    /**
41003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * Add support for a subtitle format in {@link MediaPlayer}.
41103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     *
41203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * @param renderer a {@link SubtitleController.Renderer} object that adds
41303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     *                 support for a subtitle format.
41403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     */
41503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public void registerRenderer(Renderer renderer) {
416d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar        synchronized(mRenderers) {
417d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            // TODO how to get available renderers in the system
418d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            if (!mRenderers.contains(renderer)) {
419d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                // TODO should added renderers override existing ones (to allow replacing?)
420d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar                mRenderers.add(renderer);
421d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar            }
42203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
4233cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih    }
4243cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih
4253cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih    /** @hide */
4263cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih    public boolean hasRendererFor(MediaFormat format) {
4273cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih        synchronized(mRenderers) {
4283cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih            // TODO how to get available renderers in the system
4293cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih            for (Renderer renderer: mRenderers) {
4303cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih                if (renderer.supports(format)) {
4313cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih                    return true;
4323cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih                }
4333cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih            }
4343cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih            return false;
4353cdf7c5b622a8fbb20410736bdab5888d0e1873cRobert Shih        }
43603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
43703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
43803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    /**
439d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette     * Subtitle anchor, an object that is able to display a subtitle renderer,
44003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     * e.g. a VideoView.
44103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar     */
44203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public interface Anchor {
44303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        /**
444d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette         * Anchor should use the supplied subtitle rendering widget, or
445d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette         * none if it is null.
446d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette         * @hide
44703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         */
448d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette        public void setSubtitleWidget(RenderingWidget subtitleWidget);
44929f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar
45029f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        /**
45129f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar         * Anchors provide the looper on which all track visibility changes
45229f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar         * (track.show/hide, setSubtitleWidget) will take place.
45329f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar         * @hide
45429f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar         */
45529f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        public Looper getSubtitleLooper();
45603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
45703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
45803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    private Anchor mAnchor;
45903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
46029f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    /**
46129f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar     *  @hide - called from anchor's looper (if any, both when unsetting and
46229f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar     *  setting)
46329f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar     */
46403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public void setAnchor(Anchor anchor) {
46503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (mAnchor == anchor) {
46603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar            return;
46703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
46803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
46903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (mAnchor != null) {
47029f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            checkAnchorLooper();
471d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette            mAnchor.setSubtitleWidget(null);
47203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
47303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        mAnchor = anchor;
47429f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        mHandler = null;
47503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        if (mAnchor != null) {
47629f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            mHandler = new Handler(mAnchor.getSubtitleLooper(), mCallback);
47729f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            checkAnchorLooper();
478d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette            mAnchor.setSubtitleWidget(getRenderingWidget());
47903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        }
48003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
48103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
48229f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private void checkAnchorLooper() {
48329f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        assert mHandler != null : "Should have a looper already";
48429f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        assert Looper.myLooper() == mHandler.getLooper() : "Must be called from the anchor's looper";
48529f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    }
48629f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar
48729f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    private void processOnAnchor(Message m) {
48829f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        assert mHandler != null : "Should have a looper already";
48929f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        if (Looper.myLooper() == mHandler.getLooper()) {
49029f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            mHandler.dispatchMessage(m);
49129f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        } else {
49229f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar            mHandler.sendMessage(m);
49329f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar        }
49429f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar    }
49529f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar
49603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    public interface Listener {
49703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        /**
49803c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * Called when a subtitle track has been selected.
49903c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         *
50003c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * @param track selected subtitle track or null
50103c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         * @hide
50203c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar         */
50303c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar        public void onSubtitleTrackSelected(SubtitleTrack track);
50403c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    }
50503c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar
50603c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar    private Listener mListener;
50703c25794b66b0d01e0e850042713f8009c787dc2Lajos Molnar}
508