1 /* 2 * Copyright 2020 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.settings.device.displaysound; 18 19 import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_CLASSIC; 20 import static com.android.tv.settings.util.InstrumentationUtils.logToggleInteracted; 21 22 import android.app.tvsettings.TvSettingsEnums; 23 import android.content.Context; 24 import android.os.Bundle; 25 import android.provider.Settings; 26 27 import androidx.annotation.Keep; 28 import androidx.annotation.VisibleForTesting; 29 import androidx.preference.Preference; 30 import androidx.preference.PreferenceGroup; 31 32 import com.android.tv.settings.R; 33 import com.android.tv.settings.RadioPreference; 34 import com.android.tv.settings.SettingsPreferenceFragment; 35 import com.android.tv.settings.overlay.FlavorUtils; 36 37 /** 38 * This Fragment is responsible for allowing the user to express a preference for matching the 39 * display frame rate to to the frame rate of a video being played. 40 */ 41 @Keep 42 public class MatchContentFrameRateFragment extends SettingsPreferenceFragment { 43 44 private static final String KEY_MATCH_CONTENT_FRAME_RATE = "match_content_frame_rate_option"; 45 46 private static final String KEY_MATCH_CONTENT_FRAME_RATE_SEAMLESS = 47 "match_content_frame_rate_seamless"; 48 private static final String KEY_MATCH_CONTENT_FRAME_RATE_NON_SEAMLESS = 49 "match_content_frame_rate_non_seamless"; 50 private static final String KEY_MATCH_CONTENT_FRAME_RATE_NEVER = 51 "match_content_frame_rate_never"; 52 53 private String mCurrentPreferenceKey; 54 55 56 /** @return the new instance of the class */ newInstance()57 public static MatchContentFrameRateFragment newInstance() { 58 return new MatchContentFrameRateFragment(); 59 } 60 61 @Override onAttach(Context context)62 public void onAttach(Context context) { 63 super.onAttach(context); 64 } 65 66 @Override onCreatePreferences(Bundle savedInstanceState, String rootKey)67 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 68 setPreferencesFromResource(R.xml.match_content_frame_rate, null); 69 70 // Do not show sidebar info texts in case of 1 panel settings. 71 if (FlavorUtils.getFlavor(getContext()) != FLAVOR_CLASSIC) { 72 createInfoFragments(); 73 } 74 mCurrentPreferenceKey = preferenceKeyFromSetting(); 75 getRadioPreference(mCurrentPreferenceKey).setChecked(true); 76 getRadioPreference(mCurrentPreferenceKey).clearOtherRadioPreferences(getPreferenceGroup()); 77 } 78 79 @VisibleForTesting getPreferenceGroup()80 PreferenceGroup getPreferenceGroup() { 81 return (PreferenceGroup) findPreference(KEY_MATCH_CONTENT_FRAME_RATE); 82 } 83 84 @VisibleForTesting getRadioPreference(String key)85 RadioPreference getRadioPreference(String key) { 86 return (RadioPreference) findPreference(key); 87 } 88 89 @Override onResume()90 public void onResume() { 91 super.onResume(); 92 } 93 94 95 @Override onPreferenceTreeClick(Preference preference)96 public boolean onPreferenceTreeClick(Preference preference) { 97 final String key = preference.getKey(); 98 if (key == null) { 99 return super.onPreferenceTreeClick(preference); 100 } 101 if (preference instanceof RadioPreference) { 102 final RadioPreference radioPreference = (RadioPreference) preference; 103 radioPreference.setChecked(true); 104 radioPreference.clearOtherRadioPreferences(getPreferenceGroup()); 105 106 if (key != mCurrentPreferenceKey) { 107 int newValue; 108 switch (key) { 109 case KEY_MATCH_CONTENT_FRAME_RATE_SEAMLESS: { 110 newValue = Settings.Secure.MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY; 111 break; 112 } 113 case KEY_MATCH_CONTENT_FRAME_RATE_NON_SEAMLESS: { 114 newValue = Settings.Secure.MATCH_CONTENT_FRAMERATE_ALWAYS; 115 break; 116 } 117 case KEY_MATCH_CONTENT_FRAME_RATE_NEVER: { 118 newValue = Settings.Secure.MATCH_CONTENT_FRAMERATE_NEVER; 119 break; 120 } 121 default: 122 throw new IllegalArgumentException( 123 "Unknown match content frame rate pref value" 124 + ": " + key); 125 } 126 127 int oldValue = getCurrentSettingValue(); 128 if (newValue != oldValue) { 129 Settings.Secure.putInt( 130 getContext().getContentResolver(), 131 Settings.Secure.MATCH_CONTENT_FRAME_RATE, 132 newValue); 133 logToggleInteracted(toggleIdFromSetting(oldValue), false); 134 logToggleInteracted(toggleIdFromSetting(newValue), true); 135 } 136 } 137 } 138 return super.onPreferenceTreeClick(preference); 139 } 140 141 @Override getPageId()142 protected int getPageId() { 143 return TvSettingsEnums.DISPLAY_SOUND_MATCH_CONTENT_FRAMERATE; 144 } 145 getCurrentSettingValue()146 private int getCurrentSettingValue() { 147 return Settings.Secure.getInt( 148 getContext().getContentResolver(), 149 Settings.Secure.MATCH_CONTENT_FRAME_RATE, 150 Settings.Secure.MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY); 151 } 152 preferenceKeyFromSetting()153 private String preferenceKeyFromSetting() { 154 int matchContentSetting = getCurrentSettingValue(); 155 switch (matchContentSetting) { 156 case (Settings.Secure.MATCH_CONTENT_FRAMERATE_NEVER): { 157 return KEY_MATCH_CONTENT_FRAME_RATE_NEVER; 158 } 159 case (Settings.Secure.MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY): { 160 return KEY_MATCH_CONTENT_FRAME_RATE_SEAMLESS; 161 } 162 case (Settings.Secure.MATCH_CONTENT_FRAMERATE_ALWAYS): { 163 return KEY_MATCH_CONTENT_FRAME_RATE_NON_SEAMLESS; 164 } 165 default: 166 throw new IllegalArgumentException("Unknown match content frame rate pref " 167 + "value in stored settings"); 168 } 169 } 170 toggleIdFromSetting(int matchContentSetting)171 private int toggleIdFromSetting(int matchContentSetting) { 172 switch (matchContentSetting) { 173 case Settings.Secure.MATCH_CONTENT_FRAMERATE_NEVER: 174 return TvSettingsEnums.DISPLAY_SOUND_MATCH_CONTENT_FRAMERATE_NEVER; 175 case Settings.Secure.MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY: 176 return TvSettingsEnums.DISPLAY_SOUND_MATCH_CONTENT_FRAMERATE_SEAMLESS; 177 case Settings.Secure.MATCH_CONTENT_FRAMERATE_ALWAYS: 178 return TvSettingsEnums.DISPLAY_SOUND_MATCH_CONTENT_FRAMERATE_NON_SEAMLESS; 179 default: 180 throw new IllegalArgumentException("Unknown match content frame rate pref value"); 181 } 182 } 183 createInfoFragments()184 private void createInfoFragments() { 185 Preference seamlessPreference = findPreference(KEY_MATCH_CONTENT_FRAME_RATE_SEAMLESS); 186 seamlessPreference.setFragment( 187 MatchContentFrameRateInfo.SeamlessInfoFragment.class.getName()); 188 189 Preference nonSeamlessPreference = findPreference( 190 KEY_MATCH_CONTENT_FRAME_RATE_NON_SEAMLESS); 191 nonSeamlessPreference.setFragment( 192 MatchContentFrameRateInfo.NonSeamlessInfoFragment.class.getName()); 193 194 Preference neverPreference = findPreference(KEY_MATCH_CONTENT_FRAME_RATE_NEVER); 195 neverPreference.setFragment(MatchContentFrameRateInfo.NeverInfoFragment.class.getName()); 196 } 197 }