diff --git a/res/xml/captioning_appearance.xml b/res/xml/captioning_appearance.xml index cfddff221e6..6710ec665b5 100644 --- a/res/xml/captioning_appearance.xml +++ b/res/xml/captioning_appearance.xml @@ -33,7 +33,8 @@ android:entryValues="@array/captioning_font_size_selector_values" android:key="captioning_font_size" android:summary="%s" - android:title="@string/captioning_text_size"/> + android:title="@string/captioning_text_size" + settings:controller="com.android.settings.accessibility.CaptionFontSizeController"/> + android:title="@string/captioning_typeface" + settings:controller="com.android.settings.accessibility.CaptionTypefaceController"/> mPreferenceList = new ArrayList<>(); - @Override public int getMetricsCategory() { return SettingsEnums.ACCESSIBILITY_CAPTION_APPEARANCE; @@ -92,6 +79,7 @@ public class CaptionAppearanceFragment extends DashboardFragment super.onCreatePreferences(savedInstanceState, rootKey); mCaptioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE); + mCaptionHelper = new CaptionHelper(getContext()); initializeAllPreferences(); updateAllPreferences(); @@ -118,12 +106,6 @@ public class CaptionAppearanceFragment extends DashboardFragment mPreset.setValues(presetValues); mPreset.setTitles(presetTitles); - mFontSize = (ListPreference) findPreference(PREF_FONT_SIZE); - - // Initialize the preference list - mPreferenceList.add(mFontSize); - mPreferenceList.add(mPreset); - mCustom = (PreferenceCategory) findPreference(PREF_CUSTOM); mShowingCustom = true; @@ -168,7 +150,6 @@ public class CaptionAppearanceFragment extends DashboardFragment mWindowOpacity.setValues(opacityValues); mEdgeType = (EdgeTypePreference) mCustom.findPreference(PREF_EDGE_TYPE); - mTypeface = (ListPreference) mCustom.findPreference(PREF_TYPEFACE); } private void installUpdateListeners() { @@ -181,18 +162,12 @@ public class CaptionAppearanceFragment extends DashboardFragment mWindowColor.setOnValueChangedListener(this); mWindowOpacity.setOnValueChangedListener(this); mEdgeType.setOnValueChangedListener(this); - - mTypeface.setOnPreferenceChangeListener(this); - mFontSize.setOnPreferenceChangeListener(this); } private void updateAllPreferences() { final int preset = mCaptioningManager.getRawUserStyle(); mPreset.setValue(preset); - final float fontSize = mCaptioningManager.getFontScale(); - mFontSize.setValue(Float.toString(fontSize)); - final ContentResolver cr = getContentResolver(); final CaptioningManager.CaptionStyle attrs = CaptioningManager.CaptionStyle.getCustomStyle( cr); @@ -210,9 +185,6 @@ public class CaptionAppearanceFragment extends DashboardFragment final int windowColor = attrs.hasWindowColor() ? attrs.windowColor : CaptioningManager.CaptionStyle.COLOR_UNSPECIFIED; parseColorOpacity(mWindowColor, mWindowOpacity, windowColor); - - final String rawTypeface = attrs.mRawTypeface; - mTypeface.setValue(rawTypeface == null ? "" : rawTypeface); } /** @@ -297,32 +269,7 @@ public class CaptionAppearanceFragment extends DashboardFragment } else if (mEdgeType == preference) { Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, value); } - enableCaptioningManager(); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - final ContentResolver cr = getActivity().getContentResolver(); - if (mTypeface == preference) { - Settings.Secure.putString( - cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE, (String) value); - enableCaptioningManager(); - } else if (mFontSize == preference) { - Settings.Secure.putFloat( - cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, - Float.parseFloat((String) value)); - enableCaptioningManager(); - } - - return true; - } - - private void enableCaptioningManager() { - if (mCaptioningManager.isEnabled()) { - return; - } - Settings.Secure.putInt(getContentResolver(), - Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, ON); + mCaptionHelper.setEnabled(true); } @Override diff --git a/src/com/android/settings/accessibility/CaptionFontSizeController.java b/src/com/android/settings/accessibility/CaptionFontSizeController.java new file mode 100644 index 00000000000..a8cdce598ae --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionFontSizeController.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.accessibility; + +import android.content.ContentResolver; +import android.content.Context; +import android.provider.Settings; +import android.view.accessibility.CaptioningManager; + +import androidx.preference.ListPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.core.BasePreferenceController; + +/** Preference controller for caption font size. */ +public class CaptionFontSizeController extends BasePreferenceController + implements Preference.OnPreferenceChangeListener { + + private final CaptioningManager mCaptioningManager; + private final CaptionHelper mCaptionHelper; + private ListPreference mPreference; + + public CaptionFontSizeController(Context context, String preferenceKey) { + super(context, preferenceKey); + mCaptioningManager = context.getSystemService(CaptioningManager.class); + mCaptionHelper = new CaptionHelper(context); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + + final float fontSize = mCaptioningManager.getFontScale(); + mPreference.setValue(Float.toString(fontSize)); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final ContentResolver cr = mContext.getContentResolver(); + Settings.Secure.putFloat( + cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, + Float.parseFloat((String) newValue)); + mPreference.setValue((String) newValue); + mCaptionHelper.setEnabled(true); + return false; + } +} diff --git a/src/com/android/settings/accessibility/CaptionHelper.java b/src/com/android/settings/accessibility/CaptionHelper.java index 378d4b3091c..c833272df72 100644 --- a/src/com/android/settings/accessibility/CaptionHelper.java +++ b/src/com/android/settings/accessibility/CaptionHelper.java @@ -16,7 +16,11 @@ package com.android.settings.accessibility; +import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; +import static com.android.settings.accessibility.AccessibilityUtil.State.ON; + import android.content.Context; +import android.provider.Settings; import android.view.View; import android.view.accessibility.CaptioningManager; @@ -45,6 +49,29 @@ public class CaptionHelper { mCaptioningManager = context.getSystemService(CaptioningManager.class); } + /** + * Sets the user's preferred captioning enabled state. + * + * @param enabled Whether to enable or disable captioning manager. + */ + public void setEnabled(boolean enabled) { + if (isEnabled() == enabled) { + return; + } + + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, enabled ? ON : OFF); + } + + /** + * Gets if the captioning manager is enabled. + * + * @return True if the captioning manager is enabled, false otherwise. + */ + public boolean isEnabled() { + return mCaptioningManager.isEnabled(); + } + /** * Updates font style of captioning properties for preview screen. * diff --git a/src/com/android/settings/accessibility/CaptionTogglePreferenceController.java b/src/com/android/settings/accessibility/CaptionTogglePreferenceController.java index d0ea1f953ca..bc305c1893f 100644 --- a/src/com/android/settings/accessibility/CaptionTogglePreferenceController.java +++ b/src/com/android/settings/accessibility/CaptionTogglePreferenceController.java @@ -16,12 +16,7 @@ package com.android.settings.accessibility; -import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; -import static com.android.settings.accessibility.AccessibilityUtil.State.ON; - import android.content.Context; -import android.provider.Settings; -import android.view.accessibility.CaptioningManager; import android.widget.Switch; import androidx.preference.PreferenceScreen; @@ -35,11 +30,11 @@ import com.android.settingslib.widget.OnMainSwitchChangeListener; public class CaptionTogglePreferenceController extends TogglePreferenceController implements OnMainSwitchChangeListener { - private final CaptioningManager mCaptioningManager; + private final CaptionHelper mCaptionHelper; public CaptionTogglePreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); - mCaptioningManager = context.getSystemService(CaptioningManager.class); + mCaptionHelper = new CaptionHelper(context); } @Override @@ -49,13 +44,12 @@ public class CaptionTogglePreferenceController extends TogglePreferenceControlle @Override public boolean isChecked() { - return mCaptioningManager.isEnabled(); + return mCaptionHelper.isEnabled(); } @Override public boolean setChecked(boolean isChecked) { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, isChecked ? ON : OFF); + mCaptionHelper.setEnabled(isChecked); return true; } diff --git a/src/com/android/settings/accessibility/CaptionTypefaceController.java b/src/com/android/settings/accessibility/CaptionTypefaceController.java new file mode 100644 index 00000000000..44049b07840 --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionTypefaceController.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.accessibility; + +import android.content.ContentResolver; +import android.content.Context; +import android.provider.Settings; +import android.view.accessibility.CaptioningManager.CaptionStyle; + +import androidx.preference.ListPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.core.BasePreferenceController; + +/** Preference controller for caption type face. */ +public class CaptionTypefaceController extends BasePreferenceController + implements Preference.OnPreferenceChangeListener { + + private final CaptionHelper mCaptionHelper; + private ListPreference mPreference; + + public CaptionTypefaceController(Context context, String preferenceKey) { + super(context, preferenceKey); + mCaptionHelper = new CaptionHelper(context); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + + final ContentResolver cr = mContext.getContentResolver(); + final CaptionStyle attrs = CaptionStyle.getCustomStyle(cr); + final String rawTypeface = attrs.mRawTypeface; + mPreference.setValue(rawTypeface == null ? "" : rawTypeface); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final ContentResolver cr = mContext.getContentResolver(); + Settings.Secure.putString( + cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE, (String) newValue); + mPreference.setValue((String) newValue); + mCaptionHelper.setEnabled(true); + return false; + } +} diff --git a/tests/robotests/src/com/android/settings/accessibility/CaptionFontSizeControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionFontSizeControllerTest.java new file mode 100644 index 00000000000..c4033ef5d39 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionFontSizeControllerTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.accessibility; + +import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; +import static com.android.settings.accessibility.AccessibilityUtil.State.ON; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.provider.Settings; +import android.view.accessibility.CaptioningManager; + +import androidx.preference.ListPreference; +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowCaptioningManager; + +/** Tests for {@link CaptionFontSizeController}. */ +@RunWith(RobolectricTestRunner.class) +public class CaptionFontSizeControllerTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private PreferenceScreen mScreen; + private final Context mContext = ApplicationProvider.getApplicationContext(); + private CaptionFontSizeController mController; + private ListPreference mPreference; + private ShadowCaptioningManager mShadowCaptioningManager; + + @Before + public void setUp() { + mController = new CaptionFontSizeController(mContext, "captioning_font_size"); + mPreference = new ListPreference(mContext); + mPreference.setEntries(R.array.captioning_font_size_selector_titles); + mPreference.setEntryValues(R.array.captioning_font_size_selector_values); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class); + mShadowCaptioningManager = Shadow.extract(captioningManager); + } + + @Test + public void getAvailabilityStatus_shouldReturnAvailable() { + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } + + @Test + public void displayPreference_byDefault_shouldReturnDefault() { + mController.displayPreference(mScreen); + + assertThat(mPreference.getEntry().toString()).isEqualTo("Medium"); + } + + @Test + public void displayPreference_bySmallValue_shouldReturnSmall() { + mShadowCaptioningManager.setFontScale(0.5f); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getEntry().toString()).isEqualTo("Small"); + } + + @Test + public void onPreferenceChange_shouldReturnSmall() { + mController.displayPreference(mScreen); + + mController.onPreferenceChange(mPreference, "0.5"); + + assertThat(mPreference.getEntry().toString()).isEqualTo("Small"); + } + + @Test + public void onPreferenceChange_shouldSetCaptionEnabled() { + mShadowCaptioningManager.setEnabled(false); + mController.displayPreference(mScreen); + + mController.onPreferenceChange(mPreference, "0.5"); + + final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON; + assertThat(isCaptionEnabled).isTrue(); + } +} diff --git a/tests/robotests/src/com/android/settings/accessibility/CaptionHelperTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionHelperTest.java index 02d1b187a73..42d94540045 100644 --- a/tests/robotests/src/com/android/settings/accessibility/CaptionHelperTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionHelperTest.java @@ -16,10 +16,16 @@ package com.android.settings.accessibility; +import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; +import static com.android.settings.accessibility.AccessibilityUtil.State.ON; + +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.provider.Settings; import android.view.View; import android.view.accessibility.CaptioningManager; @@ -101,4 +107,26 @@ public class CaptionHelperTest { verify(mSubtitleView).setText(text); } + + @Test + public void enableCaptioningManager_shouldSetCaptionEnabled() { + when(mCaptioningManager.isEnabled()).thenReturn(false); + + mCaptionHelper.setEnabled(true); + + final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON; + assertThat(isCaptionEnabled).isTrue(); + } + + @Test + public void disableCaptioningManager_shouldSetCaptionDisabled() { + when(mCaptioningManager.isEnabled()).thenReturn(true); + + mCaptionHelper.setEnabled(false); + + final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON; + assertThat(isCaptionEnabled).isFalse(); + } } diff --git a/tests/robotests/src/com/android/settings/accessibility/CaptionTypefaceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionTypefaceControllerTest.java new file mode 100644 index 00000000000..f2f070ff0bc --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionTypefaceControllerTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.accessibility; + +import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; +import static com.android.settings.accessibility.AccessibilityUtil.State.ON; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.provider.Settings; +import android.view.accessibility.CaptioningManager; + +import androidx.preference.ListPreference; +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowCaptioningManager; + +/** Tests for {@link CaptionTypefaceController}. */ +@RunWith(RobolectricTestRunner.class) +public class CaptionTypefaceControllerTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private PreferenceScreen mScreen; + private final Context mContext = ApplicationProvider.getApplicationContext(); + private CaptionTypefaceController mController; + private ListPreference mPreference; + private ShadowCaptioningManager mShadowCaptioningManager; + + @Before + public void setUp() { + mController = new CaptionTypefaceController(mContext, "captioning_typeface"); + mPreference = new ListPreference(mContext); + mPreference.setEntries(R.array.captioning_typeface_selector_titles); + mPreference.setEntryValues(R.array.captioning_typeface_selector_values); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class); + mShadowCaptioningManager = Shadow.extract(captioningManager); + } + + @Test + public void getAvailabilityStatus_shouldReturnAvailable() { + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } + + @Test + public void displayPreference_byDefault_shouldReturnDefault() { + mController.displayPreference(mScreen); + + assertThat(mPreference.getEntry().toString()).isEqualTo("Default"); + } + + @Test + public void displayPreference_bySerif_shouldReturnSerif() { + Settings.Secure.putString(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE, "serif"); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getEntry().toString()).isEqualTo("Serif"); + } + + @Test + public void onPreferenceChange_bySerif_shouldReturnSerif() { + mController.displayPreference(mScreen); + + mController.onPreferenceChange(mPreference, "serif"); + + assertThat(mPreference.getEntry().toString()).isEqualTo("Serif"); + } + + @Test + public void onPreferenceChange_shouldSetCaptionEnabled() { + mShadowCaptioningManager.setEnabled(false); + mController.displayPreference(mScreen); + + mController.onPreferenceChange(mPreference, "serif"); + + final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON; + assertThat(isCaptionEnabled).isTrue(); + } +}