1 /* 2 * Copyright (C) 2015 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; 18 19 import android.content.Context; 20 import android.media.tv.TvTrackInfo; 21 import android.util.SparseArray; 22 23 import com.android.tv.data.DisplayMode; 24 import com.android.tv.util.TvSettings; 25 import com.android.tv.util.TvSettings.PipLayout; 26 import com.android.tv.util.TvSettings.PipSize; 27 import com.android.tv.util.TvSettings.PipSound; 28 29 import java.util.Locale; 30 31 /** 32 * The TvOptionsManager is responsible for keeping track of current TV options such as closed 33 * captions and display mode. Can be also used to create MenuAction items to control such options. 34 */ 35 public class TvOptionsManager { 36 public static final int OPTION_CLOSED_CAPTIONS = 0; 37 public static final int OPTION_DISPLAY_MODE = 1; 38 public static final int OPTION_IN_APP_PIP = 2; 39 public static final int OPTION_SYSTEMWIDE_PIP = 3; 40 public static final int OPTION_MULTI_AUDIO = 4; 41 public static final int OPTION_MORE_CHANNELS = 5; 42 public static final int OPTION_SETTINGS = 6; 43 44 public static final int OPTION_PIP_INPUT = 100; 45 public static final int OPTION_PIP_SWAP = 101; 46 public static final int OPTION_PIP_SOUND = 102; 47 public static final int OPTION_PIP_LAYOUT = 103 ; 48 public static final int OPTION_PIP_SIZE = 104; 49 50 private final Context mContext; 51 private final SparseArray<OptionChangedListener> mOptionChangedListeners = new SparseArray<>(); 52 53 private String mClosedCaptionsLanguage; 54 private int mDisplayMode; 55 private boolean mPip; 56 private String mMultiAudio; 57 private String mPipInput; 58 private boolean mPipSwap; 59 @PipSound private int mPipSound; 60 @PipLayout private int mPipLayout; 61 @PipSize private int mPipSize; 62 TvOptionsManager(Context context)63 public TvOptionsManager(Context context) { 64 mContext = context; 65 } 66 getOptionString(int option)67 public String getOptionString(int option) { 68 switch (option) { 69 case OPTION_CLOSED_CAPTIONS: 70 if (mClosedCaptionsLanguage == null) { 71 return mContext.getString(R.string.closed_caption_option_item_off); 72 } 73 return new Locale(mClosedCaptionsLanguage).getDisplayName(); 74 case OPTION_DISPLAY_MODE: 75 return ((MainActivity) mContext).getTvViewUiManager() 76 .isDisplayModeAvailable(mDisplayMode) 77 ? DisplayMode.getLabel(mDisplayMode, mContext) 78 : DisplayMode.getLabel(DisplayMode.MODE_NORMAL, mContext); 79 case OPTION_IN_APP_PIP: 80 return mContext.getString( 81 mPip ? R.string.options_item_pip_on : R.string.options_item_pip_off); 82 case OPTION_MULTI_AUDIO: 83 return mMultiAudio; 84 case OPTION_PIP_INPUT: 85 return mPipInput; 86 case OPTION_PIP_SWAP: 87 return mContext.getString(mPipSwap ? R.string.pip_options_item_swap_on 88 : R.string.pip_options_item_swap_off); 89 case OPTION_PIP_SOUND: 90 if (mPipSound == TvSettings.PIP_SOUND_MAIN) { 91 return mContext.getString(R.string.pip_options_item_sound_main); 92 } else if (mPipSound == TvSettings.PIP_SOUND_PIP_WINDOW) { 93 return mContext.getString(R.string.pip_options_item_sound_pip_window); 94 } 95 break; 96 case OPTION_PIP_LAYOUT: 97 if (mPipLayout == TvSettings.PIP_LAYOUT_BOTTOM_RIGHT) { 98 return mContext.getString(R.string.pip_options_item_layout_bottom_right); 99 } else if (mPipLayout == TvSettings.PIP_LAYOUT_TOP_RIGHT) { 100 return mContext.getString(R.string.pip_options_item_layout_top_right); 101 } else if (mPipLayout == TvSettings.PIP_LAYOUT_TOP_LEFT) { 102 return mContext.getString(R.string.pip_options_item_layout_top_left); 103 } else if (mPipLayout == TvSettings.PIP_LAYOUT_BOTTOM_LEFT) { 104 return mContext.getString(R.string.pip_options_item_layout_bottom_left); 105 } else if (mPipLayout == TvSettings.PIP_LAYOUT_SIDE_BY_SIDE) { 106 return mContext.getString(R.string.pip_options_item_layout_side_by_side); 107 } 108 break; 109 case OPTION_PIP_SIZE: 110 if (mPipSize == TvSettings.PIP_SIZE_BIG) { 111 return mContext.getString(R.string.pip_options_item_size_big); 112 } else if (mPipSize == TvSettings.PIP_SIZE_SMALL) { 113 return mContext.getString(R.string.pip_options_item_size_small); 114 } 115 break; 116 } 117 return ""; 118 } 119 onClosedCaptionsChanged(TvTrackInfo track)120 public void onClosedCaptionsChanged(TvTrackInfo track) { 121 mClosedCaptionsLanguage = (track == null) ? null 122 : (track.getLanguage() != null) ? track.getLanguage() 123 : mContext.getString(R.string.default_language); 124 notifyOptionChanged(OPTION_CLOSED_CAPTIONS); 125 } 126 onDisplayModeChanged(int displayMode)127 public void onDisplayModeChanged(int displayMode) { 128 mDisplayMode = displayMode; 129 notifyOptionChanged(OPTION_DISPLAY_MODE); 130 } 131 onPipChanged(boolean pip)132 public void onPipChanged(boolean pip) { 133 mPip = pip; 134 notifyOptionChanged(OPTION_IN_APP_PIP); 135 } 136 onMultiAudioChanged(String multiAudio)137 public void onMultiAudioChanged(String multiAudio) { 138 mMultiAudio = multiAudio; 139 notifyOptionChanged(OPTION_MULTI_AUDIO); 140 } 141 onPipInputChanged(String pipInput)142 public void onPipInputChanged(String pipInput) { 143 mPipInput = pipInput; 144 notifyOptionChanged(OPTION_PIP_INPUT); 145 } 146 onPipSwapChanged(boolean pipSwap)147 public void onPipSwapChanged(boolean pipSwap) { 148 mPipSwap = pipSwap; 149 notifyOptionChanged(OPTION_PIP_SWAP); 150 } 151 onPipSoundChanged(@ipSound int pipSound)152 public void onPipSoundChanged(@PipSound int pipSound) { 153 mPipSound = pipSound; 154 notifyOptionChanged(OPTION_PIP_SOUND); 155 } 156 onPipLayoutChanged(@ipLayout int pipLayout)157 public void onPipLayoutChanged(@PipLayout int pipLayout) { 158 mPipLayout = pipLayout; 159 notifyOptionChanged(OPTION_PIP_LAYOUT); 160 } 161 onPipSizeChanged(@ipSize int pipSize)162 public void onPipSizeChanged(@PipSize int pipSize) { 163 mPipSize = pipSize; 164 notifyOptionChanged(OPTION_PIP_SIZE); 165 } 166 notifyOptionChanged(int option)167 private void notifyOptionChanged(int option) { 168 OptionChangedListener listener = mOptionChangedListeners.get(option); 169 if (listener != null) { 170 listener.onOptionChanged(getOptionString(option)); 171 } 172 } 173 setOptionChangedListener(int option, OptionChangedListener listener)174 public void setOptionChangedListener(int option, OptionChangedListener listener) { 175 mOptionChangedListeners.put(option, listener); 176 } 177 178 /** 179 * An interface used to monitor option changes. 180 */ 181 public interface OptionChangedListener { onOptionChanged(String newOption)182 void onOptionChanged(String newOption); 183 } 184 } 185