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