1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tv.dvr.ui.playback; 18 19 import android.media.tv.TvTrackInfo; 20 import android.os.Bundle; 21 import android.support.annotation.NonNull; 22 import androidx.leanback.app.GuidedStepFragment; 23 import androidx.leanback.widget.GuidedAction; 24 import android.text.TextUtils; 25 import android.transition.Transition; 26 import android.view.LayoutInflater; 27 import android.view.View; 28 import android.view.ViewGroup; 29 import com.android.tv.R; 30 import com.android.tv.util.TvSettings; 31 import java.util.List; 32 import java.util.Locale; 33 34 /** Fragment for DVR playback closed-caption/multi-audio settings. */ 35 public class DvrPlaybackSideFragment extends GuidedStepFragment { 36 /** The tag for passing track infos to side fragments. */ 37 public static final String TRACK_INFOS = "dvr_key_track_infos"; 38 /** The tag for passing selected track's ID to side fragments. */ 39 public static final String SELECTED_TRACK_ID = "dvr_key_selected_track_id"; 40 41 private static final int ACTION_ID_NO_SUBTITLE = -1; 42 private static final int CHECK_SET_ID = 1; 43 44 private List<TvTrackInfo> mTrackInfos; 45 private String mSelectedTrackId; 46 private TvTrackInfo mSelectedTrack; 47 private int mTrackType; 48 private DvrPlaybackOverlayFragment mOverlayFragment; 49 50 @Override onCreate(Bundle savedInstanceState)51 public void onCreate(Bundle savedInstanceState) { 52 mTrackInfos = getArguments().getParcelableArrayList(TRACK_INFOS); 53 mTrackType = mTrackInfos.get(0).getType(); 54 mSelectedTrackId = getArguments().getString(SELECTED_TRACK_ID); 55 mOverlayFragment = 56 ((DvrPlaybackOverlayFragment) 57 getFragmentManager().findFragmentById(R.id.dvr_playback_controls_fragment)); 58 super.onCreate(savedInstanceState); 59 } 60 61 @Override onCreateBackgroundView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)62 public View onCreateBackgroundView( 63 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 64 View backgroundView = super.onCreateBackgroundView(inflater, container, savedInstanceState); 65 backgroundView.setBackgroundColor( 66 getResources().getColor(R.color.lb_playback_controls_background_light)); 67 return backgroundView; 68 } 69 70 @Override onCreateActions(@onNull List<GuidedAction> actions, Bundle savedInstanceState)71 public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) { 72 if (mTrackType == TvTrackInfo.TYPE_SUBTITLE) { 73 actions.add( 74 new GuidedAction.Builder(getActivity()) 75 .id(ACTION_ID_NO_SUBTITLE) 76 .title(getString(R.string.closed_caption_option_item_off)) 77 .checkSetId(CHECK_SET_ID) 78 .checked(mSelectedTrackId == null) 79 .build()); 80 } 81 for (int i = 0; i < mTrackInfos.size(); i++) { 82 TvTrackInfo info = mTrackInfos.get(i); 83 boolean checked = TextUtils.equals(info.getId(), mSelectedTrackId); 84 GuidedAction action = 85 new GuidedAction.Builder(getActivity()) 86 .id(i) 87 .title(getTrackLabel(info, i)) 88 .checkSetId(CHECK_SET_ID) 89 .checked(checked) 90 .build(); 91 actions.add(action); 92 if (checked) { 93 mSelectedTrack = info; 94 } 95 } 96 } 97 98 @Override onGuidedActionFocused(GuidedAction action)99 public void onGuidedActionFocused(GuidedAction action) { 100 int actionId = (int) action.getId(); 101 mOverlayFragment.selectTrack(mTrackType, actionId < 0 ? null : mTrackInfos.get(actionId)); 102 } 103 104 @Override onGuidedActionClicked(GuidedAction action)105 public void onGuidedActionClicked(GuidedAction action) { 106 int actionId = (int) action.getId(); 107 mSelectedTrack = actionId < 0 ? null : mTrackInfos.get(actionId); 108 TvSettings.setDvrPlaybackTrackSettings(getContext(), mTrackType, mSelectedTrack); 109 getFragmentManager().popBackStack(); 110 } 111 112 @Override 113 public void onStart() { 114 super.onStart(); 115 // Workaround: when overlay fragment is faded out, any focus will lost due to overlay 116 // fragment's implementation. So we disable overlay fragment's fading here to prevent 117 // losing focus while users are interacting with the side fragment. 118 mOverlayFragment.setFadingEnabled(false); 119 } 120 121 @Override 122 public void onStop() { 123 super.onStop(); 124 // We disable fading of overlay fragment to prevent side fragment from losing focus, 125 // therefore we should resume it here. 126 mOverlayFragment.setFadingEnabled(true); 127 mOverlayFragment.selectTrack(mTrackType, mSelectedTrack); 128 } 129 130 private String getTrackLabel(TvTrackInfo track, int trackIndex) { 131 if (track.getLanguage() != null) { 132 return new Locale(track.getLanguage()).getDisplayName(); 133 } 134 return track.getType() == TvTrackInfo.TYPE_SUBTITLE 135 ? getString(R.string.closed_caption_unknown_language, trackIndex + 1) 136 : getString(R.string.multi_audio_unknown_language); 137 } 138 139 @Override 140 protected void onProvideFragmentTransitions() { 141 super.onProvideFragmentTransitions(); 142 // Excludes the background scrim from transition to prevent the blinking caused by 143 // hiding the overlay fragment and sliding in the side fragment at the same time. 144 Transition t = getEnterTransition(); 145 if (t != null) { 146 t.excludeTarget(R.id.guidedstep_background, true); 147 } 148 } 149 } 150