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 android.support.v17.leanback.app.GuidedStepFragment; 23 import android.support.v17.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 30 import com.android.tv.R; 31 import com.android.tv.util.TvSettings; 32 33 import java.util.List; 34 import java.util.Locale; 35 36 /** 37 * Fragment for DVR playback closed-caption/multi-audio settings. 38 */ 39 public class DvrPlaybackSideFragment extends GuidedStepFragment { 40 /** 41 * The tag for passing track infos to side fragments. 42 */ 43 public static final String TRACK_INFOS = "dvr_key_track_infos"; 44 /** 45 * The tag for passing selected track's ID to side fragments. 46 */ 47 public static final String SELECTED_TRACK_ID = "dvr_key_selected_track_id"; 48 49 private static final int ACTION_ID_NO_SUBTITLE = -1; 50 private static final int CHECK_SET_ID = 1; 51 52 private List<TvTrackInfo> mTrackInfos; 53 private String mSelectedTrackId; 54 private TvTrackInfo mSelectedTrack; 55 private int mTrackType; 56 private DvrPlaybackOverlayFragment mOverlayFragment; 57 58 @Override onCreate(Bundle savedInstanceState)59 public void onCreate(Bundle savedInstanceState) { 60 mTrackInfos = getArguments().getParcelableArrayList(TRACK_INFOS); 61 mTrackType = mTrackInfos.get(0).getType(); 62 mSelectedTrackId = getArguments().getString(SELECTED_TRACK_ID); 63 mOverlayFragment = ((DvrPlaybackOverlayFragment) getFragmentManager() 64 .findFragmentById(R.id.dvr_playback_controls_fragment)); 65 super.onCreate(savedInstanceState); 66 } 67 68 @Override onCreateBackgroundView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)69 public View onCreateBackgroundView(LayoutInflater inflater, ViewGroup container, 70 Bundle savedInstanceState) { 71 View backgroundView = super.onCreateBackgroundView(inflater, container, savedInstanceState); 72 backgroundView.setBackgroundColor(getResources() 73 .getColor(R.color.lb_playback_controls_background_light)); 74 return backgroundView; 75 } 76 77 @Override onCreateActions(@onNull List<GuidedAction> actions, Bundle savedInstanceState)78 public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) { 79 if (mTrackType == TvTrackInfo.TYPE_SUBTITLE) { 80 actions.add(new GuidedAction.Builder(getActivity()) 81 .id(ACTION_ID_NO_SUBTITLE) 82 .title(getString(R.string.closed_caption_option_item_off)) 83 .checkSetId(CHECK_SET_ID) 84 .checked(mSelectedTrackId == null) 85 .build()); 86 } 87 for (int i = 0; i < mTrackInfos.size(); i++) { 88 TvTrackInfo info = mTrackInfos.get(i); 89 boolean checked = TextUtils.equals(info.getId(), mSelectedTrackId); 90 GuidedAction action = new GuidedAction.Builder(getActivity()) 91 .id(i) 92 .title(getTrackLabel(info, i)) 93 .checkSetId(CHECK_SET_ID) 94 .checked(checked) 95 .build(); 96 actions.add(action); 97 if (checked) { 98 mSelectedTrack = info; 99 } 100 } 101 } 102 103 @Override onGuidedActionFocused(GuidedAction action)104 public void onGuidedActionFocused(GuidedAction action) { 105 int actionId = (int) action.getId(); 106 mOverlayFragment.selectTrack(mTrackType, actionId < 0 ? null : mTrackInfos.get(actionId)); 107 } 108 109 @Override onGuidedActionClicked(GuidedAction action)110 public void onGuidedActionClicked(GuidedAction action) { 111 int actionId = (int) action.getId(); 112 mSelectedTrack = actionId < 0 ? null : mTrackInfos.get(actionId); 113 TvSettings.setDvrPlaybackTrackSettings(getContext(), mTrackType, mSelectedTrack); 114 getFragmentManager().popBackStack(); 115 } 116 117 @Override 118 public void onStart() { 119 super.onStart(); 120 // Workaround: when overlay fragment is faded out, any focus will lost due to overlay 121 // fragment's implementation. So we disable overlay fragment's fading here to prevent 122 // losing focus while users are interacting with the side fragment. 123 mOverlayFragment.setFadingEnabled(false); 124 } 125 126 @Override 127 public void onStop() { 128 super.onStop(); 129 // We disable fading of overlay fragment to prevent side fragment from losing focus, 130 // therefore we should resume it here. 131 mOverlayFragment.setFadingEnabled(true); 132 mOverlayFragment.selectTrack(mTrackType, mSelectedTrack); 133 } 134 135 private String getTrackLabel(TvTrackInfo track, int trackIndex) { 136 if (track.getLanguage() != null) { 137 return new Locale(track.getLanguage()).getDisplayName(); 138 } 139 return track.getType() == TvTrackInfo.TYPE_SUBTITLE ? 140 getString(R.string.closed_caption_unknown_language, trackIndex + 1) 141 : getString(R.string.multi_audio_unknown_language); 142 } 143 144 @Override 145 protected void onProvideFragmentTransitions() { 146 super.onProvideFragmentTransitions(); 147 // Excludes the background scrim from transition to prevent the blinking caused by 148 // hiding the overlay fragment and sliding in the side fragment at the same time. 149 Transition t = getEnterTransition(); 150 if (t != null) { 151 t.excludeTarget(R.id.guidedstep_background, true); 152 } 153 } 154 }