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.menu; 18 19 import android.content.Context; 20 import android.media.tv.TvTrackInfo; 21 import android.text.TextUtils; 22 23 import android.support.annotation.Nullable; 24 25 import com.android.tv.TvOptionsManager; 26 import com.android.tv.common.BuildConfig; 27 import com.android.tv.common.customization.CustomAction; 28 import com.android.tv.data.DisplayMode; 29 import com.android.tv.features.TvFeatures; 30 import com.android.tv.ui.TvViewUiManager; 31 import com.android.tv.ui.sidepanel.ClosedCaptionFragment; 32 import com.android.tv.ui.sidepanel.DeveloperOptionFragment; 33 import com.android.tv.ui.sidepanel.DisplayModeFragment; 34 import com.android.tv.ui.sidepanel.MultiAudioFragment; 35 36 import com.google.auto.factory.AutoFactory; 37 import com.google.auto.factory.Provided; 38 39 import com.android.tv.common.flags.LegacyFlags; 40 import com.android.tv.common.flags.UiFlags; 41 42 import java.util.ArrayList; 43 import java.util.List; 44 45 /* 46 * An adapter of options. 47 */ 48 @AutoFactory(implementing = TvOptionsRowAdapter.Factory.class) 49 public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter { 50 private final LegacyFlags mLegacyFlags; 51 private final UiFlags mUiFlags; 52 53 /** Factory for a {@link TvOptionsRowAdapter}. */ 54 public interface Factory { 55 /** Creates a {@link TvOptionsRowAdapter} */ create(Context context, @Nullable List<CustomAction> customActions)56 TvOptionsRowAdapter create(Context context, @Nullable List<CustomAction> customActions); 57 } 58 TvOptionsRowAdapter( Context context, @Nullable List<CustomAction> customActions, @Provided LegacyFlags mLegacyFlags, @Provided UiFlags uiFlags)59 public TvOptionsRowAdapter( 60 Context context, 61 @Nullable List<CustomAction> customActions, 62 @Provided LegacyFlags mLegacyFlags, 63 @Provided UiFlags uiFlags) { 64 super(context, customActions); 65 this.mLegacyFlags = mLegacyFlags; 66 mUiFlags = uiFlags; 67 } 68 69 @Override createBaseActions()70 protected List<MenuAction> createBaseActions() { 71 List<MenuAction> actionList = new ArrayList<>(); 72 actionList.add(MenuAction.SELECT_CLOSED_CAPTION_ACTION); 73 actionList.add(MenuAction.SELECT_DISPLAY_MODE_ACTION); 74 if (TvFeatures.PICTURE_IN_PICTURE.isEnabled(getMainActivity())) { 75 actionList.add(MenuAction.SYSTEMWIDE_PIP_ACTION); 76 } 77 actionList.add(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION); 78 if (!TextUtils.isEmpty(mUiFlags.moreChannelsUrl())) { 79 actionList.add(MenuAction.MORE_CHANNELS_ACTION); 80 } 81 if (BuildConfig.ENG || mLegacyFlags.enableDeveloperFeatures()) { 82 actionList.add(MenuAction.DEV_ACTION); 83 } 84 actionList.add(MenuAction.SETTINGS_ACTION); 85 86 updateClosedCaptionAction(); 87 updatePipAction(); 88 updateMultiAudioAction(); 89 updateDisplayModeAction(); 90 return actionList; 91 } 92 93 @Override updateActions()94 protected void updateActions() { 95 if (updateClosedCaptionAction()) { 96 notifyItemChanged(getItemPosition(MenuAction.SELECT_CLOSED_CAPTION_ACTION)); 97 } 98 if (updatePipAction()) { 99 notifyItemChanged(getItemPosition(MenuAction.SYSTEMWIDE_PIP_ACTION)); 100 } 101 if (updateMultiAudioAction()) { 102 notifyItemChanged(getItemPosition(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION)); 103 } 104 if (updateDisplayModeAction()) { 105 notifyItemChanged(getItemPosition(MenuAction.SELECT_DISPLAY_MODE_ACTION)); 106 } 107 } 108 updateClosedCaptionAction()109 private boolean updateClosedCaptionAction() { 110 return updateActionDescription(MenuAction.SELECT_CLOSED_CAPTION_ACTION); 111 } 112 updatePipAction()113 private boolean updatePipAction() { 114 if (containsItem(MenuAction.SYSTEMWIDE_PIP_ACTION)) { 115 return MenuAction.setEnabled( 116 MenuAction.SYSTEMWIDE_PIP_ACTION, 117 !getMainActivity().isScreenBlockedByResourceConflictOrParentalControl()); 118 } 119 return false; 120 } 121 updateMultiAudioAction()122 boolean updateMultiAudioAction() { 123 List<TvTrackInfo> audioTracks = getMainActivity().getTracks(TvTrackInfo.TYPE_AUDIO); 124 boolean enabled = audioTracks != null && audioTracks.size() > 1; 125 // Use "|" operator for non-short-circuit evaluation. 126 return MenuAction.setEnabled(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION, enabled) 127 | updateActionDescription(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION); 128 } 129 updateDisplayModeAction()130 private boolean updateDisplayModeAction() { 131 TvViewUiManager uiManager = getMainActivity().getTvViewUiManager(); 132 boolean enabled = 133 uiManager.isDisplayModeAvailable(DisplayMode.MODE_FULL) 134 || uiManager.isDisplayModeAvailable(DisplayMode.MODE_ZOOM); 135 // Use "|" operator for non-short-circuit evaluation. 136 return MenuAction.setEnabled(MenuAction.SELECT_DISPLAY_MODE_ACTION, enabled) 137 | updateActionDescription(MenuAction.SELECT_DISPLAY_MODE_ACTION); 138 } 139 updateActionDescription(MenuAction action)140 private boolean updateActionDescription(MenuAction action) { 141 return MenuAction.setActionDescription( 142 action, getMainActivity().getTvOptionsManager().getOptionString(action.getType())); 143 } 144 145 @Override executeBaseAction(int type)146 protected void executeBaseAction(int type) { 147 switch (type) { 148 case TvOptionsManager.OPTION_CLOSED_CAPTIONS: 149 getMainActivity() 150 .getOverlayManager() 151 .getSideFragmentManager() 152 .show(new ClosedCaptionFragment()); 153 break; 154 case TvOptionsManager.OPTION_DISPLAY_MODE: 155 getMainActivity() 156 .getOverlayManager() 157 .getSideFragmentManager() 158 .show(new DisplayModeFragment()); 159 break; 160 case TvOptionsManager.OPTION_SYSTEMWIDE_PIP: 161 getMainActivity().enterPictureInPictureMode(); 162 break; 163 case TvOptionsManager.OPTION_MULTI_AUDIO: 164 getMainActivity() 165 .getOverlayManager() 166 .getSideFragmentManager() 167 .show(new MultiAudioFragment()); 168 break; 169 case TvOptionsManager.OPTION_MORE_CHANNELS: 170 getMainActivity().showMerchantCollection(); 171 break; 172 case TvOptionsManager.OPTION_DEVELOPER: 173 getMainActivity() 174 .getOverlayManager() 175 .getSideFragmentManager() 176 .show(new DeveloperOptionFragment()); 177 break; 178 case TvOptionsManager.OPTION_SETTINGS: 179 getMainActivity().showSettingsFragment(); 180 break; 181 } 182 } 183 } 184