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