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