diff --git a/res/xml/captioning_appearance.xml b/res/xml/captioning_appearance.xml index 6710ec665b5..66c74e6d3d1 100644 --- a/res/xml/captioning_appearance.xml +++ b/res/xml/captioning_appearance.xml @@ -54,40 +54,47 @@ + android:title="@string/captioning_foreground_color" + settings:controller="com.android.settings.accessibility.CaptionForegroundColorController"/> + android:title="@string/captioning_foreground_opacity" + settings:controller="com.android.settings.accessibility.CaptionForegroundOpacityController"/> + android:title="@string/captioning_edge_type" + settings:controller="com.android.settings.accessibility.CaptionEdgeTypeController"/> + android:title="@string/captioning_edge_color" + settings:controller="com.android.settings.accessibility.CaptionEdgeColorController"/> + android:title="@string/captioning_background_color" + settings:controller="com.android.settings.accessibility.CaptionBackgroundColorController"/> + android:title="@string/captioning_background_opacity" + settings:controller="com.android.settings.accessibility.CaptionBackgroundOpacityController"/> + android:title="@string/captioning_window_color" + settings:controller="com.android.settings.accessibility.CaptionWindowColorController"/> - + android:title="@string/captioning_window_opacity" + settings:controller="com.android.settings.accessibility.CaptionWindowOpacityController"/> >> 24) == 0) { - // "None" color with variable alpha. - colorValue = Color.TRANSPARENT; - opacityValue = (value & 0xFF) << 24; - } else { - // Normal color. - colorValue = value | 0xFF000000; - opacityValue = value & 0xFF000000; - } - - // Opacity value is always white. - opacity.setValue(opacityValue | 0xFFFFFF); - color.setValue(colorValue); - } - - private int mergeColorOpacity(ColorPreference color, ColorPreference opacity) { - final int colorValue = color.getValue(); - final int opacityValue = opacity.getValue(); - final int value; - // "Default" is 0x00FFFFFF or, for legacy support, 0x00000100. - if (!CaptioningManager.CaptionStyle.hasColor(colorValue)) { - // Encode "default" as 0x00FFFFaa. - value = 0x00FFFF00 | Color.alpha(opacityValue); - } else if (colorValue == Color.TRANSPARENT) { - // Encode "none" as 0x000000aa. - value = Color.alpha(opacityValue); - } else { - // Encode custom color normally. - value = colorValue & 0x00FFFFFF | opacityValue & 0xFF000000; - } - return value; } private void refreshShowingCustom() { @@ -249,25 +117,9 @@ public class CaptionAppearanceFragment extends DashboardFragment @Override public void onValueChanged(ListDialogPreference preference, int value) { final ContentResolver cr = getActivity().getContentResolver(); - if (mForegroundColor == preference || mForegroundOpacity == preference) { - final int merged = mergeColorOpacity(mForegroundColor, mForegroundOpacity); - Settings.Secure.putInt( - cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, merged); - } else if (mBackgroundColor == preference || mBackgroundOpacity == preference) { - final int merged = mergeColorOpacity(mBackgroundColor, mBackgroundOpacity); - Settings.Secure.putInt( - cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, merged); - } else if (mWindowColor == preference || mWindowOpacity == preference) { - final int merged = mergeColorOpacity(mWindowColor, mWindowOpacity); - Settings.Secure.putInt( - cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, merged); - } else if (mEdgeColor == preference) { - Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, value); - } else if (mPreset == preference) { + if (mPreset == preference) { Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, value); refreshShowingCustom(); - } else if (mEdgeType == preference) { - Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, value); } mCaptionHelper.setEnabled(true); } diff --git a/src/com/android/settings/accessibility/CaptionBackgroundColorController.java b/src/com/android/settings/accessibility/CaptionBackgroundColorController.java new file mode 100644 index 00000000000..f477c9c1e0d --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionBackgroundColorController.java @@ -0,0 +1,76 @@ +/* + * 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.Context; +import android.content.res.Resources; +import android.graphics.Color; + +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.accessibility.ListDialogPreference.OnValueChangedListener; +import com.android.settings.core.BasePreferenceController; + +/** Preference controller for caption background color. */ +public class CaptionBackgroundColorController extends BasePreferenceController + implements OnValueChangedListener { + + private final CaptionHelper mCaptionHelper; + + public CaptionBackgroundColorController(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); + final ColorPreference preference = screen.findPreference(getPreferenceKey()); + final Resources res = mContext.getResources(); + final int[] colorValues = res.getIntArray(R.array.captioning_color_selector_values); + final String[] colorTitles = res.getStringArray( + R.array.captioning_color_selector_titles); + // Add "none" as an additional option for backgrounds. + final int[] backgroundColorValues = new int[colorValues.length + 1]; + final String[] backgroundColorTitles = new String[colorTitles.length + 1]; + System.arraycopy(colorValues, 0, backgroundColorValues, 1, colorValues.length); + System.arraycopy(colorTitles, 0, backgroundColorTitles, 1, colorTitles.length); + backgroundColorValues[0] = Color.TRANSPARENT; + backgroundColorTitles[0] = mContext.getString(R.string.color_none); + preference.setTitles(backgroundColorTitles); + preference.setValues(backgroundColorValues); + final int backBackgroundColor = mCaptionHelper.getBackgroundColor(); + final int color = CaptionUtils.parseColor(backBackgroundColor); + preference.setValue(color); + preference.setOnValueChangedListener(this); + } + + @Override + public void onValueChanged(ListDialogPreference preference, int value) { + final int backBackgroundColor = mCaptionHelper.getBackgroundColor(); + final int opacity = CaptionUtils.parseOpacity(backBackgroundColor); + final int merged = CaptionUtils.mergeColorOpacity(value, opacity); + mCaptionHelper.setBackgroundColor(merged); + mCaptionHelper.setEnabled(true); + } +} diff --git a/src/com/android/settings/accessibility/CaptionBackgroundOpacityController.java b/src/com/android/settings/accessibility/CaptionBackgroundOpacityController.java new file mode 100644 index 00000000000..5aeb1ddcc5e --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionBackgroundOpacityController.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.Context; +import android.content.res.Resources; + +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.accessibility.ListDialogPreference.OnValueChangedListener; +import com.android.settings.core.BasePreferenceController; + +/** Preference controller for caption background opacity. */ +public class CaptionBackgroundOpacityController extends BasePreferenceController + implements OnValueChangedListener { + + private final CaptionHelper mCaptionHelper; + + public CaptionBackgroundOpacityController(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); + final ColorPreference preference = screen.findPreference(getPreferenceKey()); + final Resources res = mContext.getResources(); + final int[] opacityValues = res.getIntArray(R.array.captioning_opacity_selector_values); + final String[] opacityTitles = res.getStringArray( + R.array.captioning_opacity_selector_titles); + preference.setTitles(opacityTitles); + preference.setValues(opacityValues); + final int backBackgroundColor = mCaptionHelper.getBackgroundColor(); + final int opacity = CaptionUtils.parseOpacity(backBackgroundColor); + preference.setValue(opacity); + preference.setOnValueChangedListener(this); + } + + @Override + public void onValueChanged(ListDialogPreference preference, int value) { + final int backBackgroundColor = mCaptionHelper.getBackgroundColor(); + final int color = CaptionUtils.parseColor(backBackgroundColor); + final int merged = CaptionUtils.mergeColorOpacity(color, value); + mCaptionHelper.setBackgroundColor(merged); + mCaptionHelper.setEnabled(true); + } +} diff --git a/src/com/android/settings/accessibility/CaptionEdgeColorController.java b/src/com/android/settings/accessibility/CaptionEdgeColorController.java new file mode 100644 index 00000000000..22359947234 --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionEdgeColorController.java @@ -0,0 +1,63 @@ +/* + * 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.Context; +import android.content.res.Resources; + +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.accessibility.ListDialogPreference.OnValueChangedListener; +import com.android.settings.core.BasePreferenceController; + +/** Preference controller for caption edge color. */ +public class CaptionEdgeColorController extends BasePreferenceController + implements OnValueChangedListener { + + private final CaptionHelper mCaptionHelper; + + public CaptionEdgeColorController(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); + final ColorPreference preference = screen.findPreference(getPreferenceKey()); + final Resources res = mContext.getResources(); + final int[] colorValues = res.getIntArray(R.array.captioning_color_selector_values); + final String[] colorTitles = res.getStringArray( + R.array.captioning_color_selector_titles); + preference.setTitles(colorTitles); + preference.setValues(colorValues); + preference.setValue(mCaptionHelper.getEdgeColor()); + preference.setOnValueChangedListener(this); + } + + @Override + public void onValueChanged(ListDialogPreference preference, int value) { + mCaptionHelper.setEdgeColor(value); + mCaptionHelper.setEnabled(true); + } +} diff --git a/src/com/android/settings/accessibility/CaptionEdgeTypeController.java b/src/com/android/settings/accessibility/CaptionEdgeTypeController.java new file mode 100644 index 00000000000..031dfaa7431 --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionEdgeTypeController.java @@ -0,0 +1,55 @@ +/* + * 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.Context; + +import androidx.preference.PreferenceScreen; + +import com.android.settings.accessibility.ListDialogPreference.OnValueChangedListener; +import com.android.settings.core.BasePreferenceController; + +/** Preference controller for caption edge type. */ +public class CaptionEdgeTypeController extends BasePreferenceController + implements OnValueChangedListener { + + private final CaptionHelper mCaptionHelper; + + public CaptionEdgeTypeController(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); + final EdgeTypePreference preference = screen.findPreference(getPreferenceKey()); + preference.setValue(mCaptionHelper.getEdgeType()); + preference.setOnValueChangedListener(this); + } + + @Override + public void onValueChanged(ListDialogPreference preference, int value) { + mCaptionHelper.setEdgeType(value); + mCaptionHelper.setEnabled(true); + } +} diff --git a/src/com/android/settings/accessibility/CaptionForegroundColorController.java b/src/com/android/settings/accessibility/CaptionForegroundColorController.java new file mode 100644 index 00000000000..b8618f353d7 --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionForegroundColorController.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.Context; +import android.content.res.Resources; + +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.accessibility.ListDialogPreference.OnValueChangedListener; +import com.android.settings.core.BasePreferenceController; + +/** Preference controller for caption foreground color. */ +public class CaptionForegroundColorController extends BasePreferenceController + implements OnValueChangedListener { + + private final CaptionHelper mCaptionHelper; + + public CaptionForegroundColorController(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); + final ColorPreference preference = screen.findPreference(getPreferenceKey()); + final Resources res = mContext.getResources(); + final int[] colorValues = res.getIntArray(R.array.captioning_color_selector_values); + final String[] colorTitles = res.getStringArray( + R.array.captioning_color_selector_titles); + preference.setTitles(colorTitles); + preference.setValues(colorValues); + final int foregroundColor = mCaptionHelper.getForegroundColor(); + final int color = CaptionUtils.parseColor(foregroundColor); + preference.setValue(color); + preference.setOnValueChangedListener(this); + } + + @Override + public void onValueChanged(ListDialogPreference preference, int value) { + final int foregroundColor = mCaptionHelper.getForegroundColor(); + final int opacity = CaptionUtils.parseOpacity(foregroundColor); + final int merged = CaptionUtils.mergeColorOpacity(value, opacity); + mCaptionHelper.setForegroundColor(merged); + mCaptionHelper.setEnabled(true); + } +} diff --git a/src/com/android/settings/accessibility/CaptionForegroundOpacityController.java b/src/com/android/settings/accessibility/CaptionForegroundOpacityController.java new file mode 100644 index 00000000000..7f31704a07c --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionForegroundOpacityController.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.Context; +import android.content.res.Resources; + +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.accessibility.ListDialogPreference.OnValueChangedListener; +import com.android.settings.core.BasePreferenceController; + +/** Preference controller for caption foreground opacity. */ +public class CaptionForegroundOpacityController extends BasePreferenceController + implements OnValueChangedListener { + + private final CaptionHelper mCaptionHelper; + + public CaptionForegroundOpacityController(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); + final ColorPreference preference = screen.findPreference(getPreferenceKey()); + final Resources res = mContext.getResources(); + final int[] opacityValues = res.getIntArray(R.array.captioning_opacity_selector_values); + final String[] opacityTitles = res.getStringArray( + R.array.captioning_opacity_selector_titles); + preference.setTitles(opacityTitles); + preference.setValues(opacityValues); + final int foregroundColor = mCaptionHelper.getForegroundColor(); + final int opacity = CaptionUtils.parseOpacity(foregroundColor); + preference.setValue(opacity); + preference.setOnValueChangedListener(this); + } + + @Override + public void onValueChanged(ListDialogPreference preference, int value) { + final int foregroundColor = mCaptionHelper.getForegroundColor(); + final int color = CaptionUtils.parseColor(foregroundColor); + final int merged = CaptionUtils.mergeColorOpacity(color, value); + mCaptionHelper.setForegroundColor(merged); + mCaptionHelper.setEnabled(true); + } +} diff --git a/src/com/android/settings/accessibility/CaptionHelper.java b/src/com/android/settings/accessibility/CaptionHelper.java index c833272df72..4c9127fa951 100644 --- a/src/com/android/settings/accessibility/CaptionHelper.java +++ b/src/com/android/settings/accessibility/CaptionHelper.java @@ -19,10 +19,12 @@ 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.ContentResolver; import android.content.Context; import android.provider.Settings; import android.view.View; import android.view.accessibility.CaptioningManager; +import android.view.accessibility.CaptioningManager.CaptionStyle; import com.android.internal.widget.SubtitleView; import com.android.settings.R; @@ -32,9 +34,7 @@ import com.google.common.annotations.VisibleForTesting; import java.util.Locale; -/** - * Helper class for caption. - */ +/** Helper class for caption. */ public class CaptionHelper { /* WebVtt specifies line height as 5.3% of the viewport height. */ @@ -42,10 +42,12 @@ public class CaptionHelper { static final float LINE_HEIGHT_RATIO = 0.0533f; private final Context mContext; + private final ContentResolver mContentResolver; private final CaptioningManager mCaptioningManager; public CaptionHelper(Context context) { mContext = context; + mContentResolver = mContext.getContentResolver(); mCaptioningManager = context.getSystemService(CaptioningManager.class); } @@ -104,4 +106,84 @@ public class CaptionHelper { previewText.setText(R.string.captioning_preview_characters); } } + + /** + * Sets the user's preferred captioning background color. + * + * @param color The captioning background color + */ + public void setBackgroundColor(int color) { + Settings.Secure.putInt(mContentResolver, + Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, color); + } + + /** Returns the captioning background color.*/ + public int getBackgroundColor() { + final CaptionStyle attrs = CaptionStyle.getCustomStyle(mContentResolver); + return attrs.hasBackgroundColor() ? attrs.backgroundColor : CaptionStyle.COLOR_UNSPECIFIED; + } + + /** + * Sets the user's preferred captioning foreground color. + * + * @param color The captioning foreground color + */ + public void setForegroundColor(int color) { + Settings.Secure.putInt(mContentResolver, + Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, color); + } + + /** Returns the captioning foreground color.*/ + public int getForegroundColor() { + final CaptionStyle attrs = CaptionStyle.getCustomStyle(mContentResolver); + return attrs.hasForegroundColor() ? attrs.foregroundColor : CaptionStyle.COLOR_UNSPECIFIED; + } + + /** + * Sets the user's preferred captioning window color. + * + * @param color The captioning window color + */ + public void setWindowColor(int color) { + Settings.Secure.putInt(mContentResolver, + Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, color); + } + + /** Returns the captioning window color.*/ + public int getWindowColor() { + final CaptionStyle attrs = CaptionStyle.getCustomStyle(mContentResolver); + return attrs.hasWindowColor() ? attrs.windowColor : CaptionStyle.COLOR_UNSPECIFIED; + } + + /** + * Sets the user's preferred captioning edge color. + * + * @param color The captioning edge color + */ + public void setEdgeColor(int color) { + Settings.Secure.putInt(mContentResolver, + Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, color); + } + + /** Returns the captioning edge color.*/ + public int getEdgeColor() { + final CaptionStyle attrs = CaptionStyle.getCustomStyle(mContentResolver); + return attrs.edgeColor; + } + + /** + * Sets the user's preferred captioning edge type. + * + * @param type The captioning edge type + */ + public void setEdgeType(int type) { + Settings.Secure.putInt(mContentResolver, + Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, type); + } + + /** Returns the captioning edge type.*/ + public int getEdgeType() { + final CaptionStyle attrs = CaptionStyle.getCustomStyle(mContentResolver); + return attrs.edgeType; + } } diff --git a/src/com/android/settings/accessibility/CaptionUtils.java b/src/com/android/settings/accessibility/CaptionUtils.java new file mode 100644 index 00000000000..3a80133df08 --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionUtils.java @@ -0,0 +1,88 @@ +/* + * 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.graphics.Color; +import android.view.accessibility.CaptioningManager.CaptionStyle; + +/** Provides utility methods related caption. */ +public final class CaptionUtils { + + /** + * Unpacks the specified color value to get the color value. + * + * @param value the specified color value. + */ + public static int parseColor(int value) { + final int colorValue; + if (!CaptionStyle.hasColor(value)) { + // "Default" color with variable alpha. + colorValue = CaptionStyle.COLOR_UNSPECIFIED; + } else if ((value >>> 24) == 0) { + // "None" color with variable alpha. + colorValue = Color.TRANSPARENT; + } else { + // Normal color. + colorValue = value | 0xFF000000; + } + return colorValue; + } + + /** + * Unpacks the specified color value to get the opacity value. + * + * @param value the specified color value. + */ + public static int parseOpacity(int value) { + final int opacityValue; + if (!CaptionStyle.hasColor(value)) { + // "Default" color with variable alpha. + opacityValue = (value & 0xFF) << 24; + } else if ((value >>> 24) == 0) { + // "None" color with variable alpha. + opacityValue = (value & 0xFF) << 24; + } else { + // Normal color. + opacityValue = value & 0xFF000000; + } + + // Opacity value is always white. + return opacityValue | 0xFFFFFF; + } + + /** + * Packs the specified color value and specified opacity value into merged color value. + * + * @param colorValue the color value. + * @param opacityValue the opacity value. + */ + public static int mergeColorOpacity(int colorValue, int opacityValue) { + final int value; + // "Default" is 0x00FFFFFF or, for legacy support, 0x00000100. + if (!CaptionStyle.hasColor(colorValue)) { + // Encode "default" as 0x00FFFFaa. + value = 0x00FFFF00 | Color.alpha(opacityValue); + } else if (colorValue == Color.TRANSPARENT) { + // Encode "none" as 0x000000aa. + value = Color.alpha(opacityValue); + } else { + // Encode custom color normally. + value = (colorValue & 0x00FFFFFF) | (opacityValue & 0xFF000000); + } + return value; + } +} diff --git a/src/com/android/settings/accessibility/CaptionWindowColorController.java b/src/com/android/settings/accessibility/CaptionWindowColorController.java new file mode 100644 index 00000000000..f13a3477930 --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionWindowColorController.java @@ -0,0 +1,76 @@ +/* + * 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.Context; +import android.content.res.Resources; +import android.graphics.Color; + +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.accessibility.ListDialogPreference.OnValueChangedListener; +import com.android.settings.core.BasePreferenceController; + +/** Preference controller for caption window color. */ +public class CaptionWindowColorController extends BasePreferenceController + implements OnValueChangedListener { + + private final CaptionHelper mCaptionHelper; + + public CaptionWindowColorController(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); + final ColorPreference preference = screen.findPreference(getPreferenceKey()); + final Resources res = mContext.getResources(); + final int[] colorValues = res.getIntArray(R.array.captioning_color_selector_values); + final String[] colorTitles = res.getStringArray( + R.array.captioning_color_selector_titles); + // Add "none" as an additional option for window backgrounds. + final int[] backgroundColorValues = new int[colorValues.length + 1]; + final String[] backgroundColorTitles = new String[colorTitles.length + 1]; + System.arraycopy(colorValues, 0, backgroundColorValues, 1, colorValues.length); + System.arraycopy(colorTitles, 0, backgroundColorTitles, 1, colorTitles.length); + backgroundColorValues[0] = Color.TRANSPARENT; + backgroundColorTitles[0] = mContext.getString(R.string.color_none); + preference.setTitles(backgroundColorTitles); + preference.setValues(backgroundColorValues); + final int windowColor = mCaptionHelper.getWindowColor(); + final int color = CaptionUtils.parseColor(windowColor); + preference.setValue(color); + preference.setOnValueChangedListener(this); + } + + @Override + public void onValueChanged(ListDialogPreference preference, int value) { + final int windowColor = mCaptionHelper.getWindowColor(); + final int opacity = CaptionUtils.parseOpacity(windowColor); + final int merged = CaptionUtils.mergeColorOpacity(value, opacity); + mCaptionHelper.setWindowColor(merged); + mCaptionHelper.setEnabled(true); + } +} diff --git a/src/com/android/settings/accessibility/CaptionWindowOpacityController.java b/src/com/android/settings/accessibility/CaptionWindowOpacityController.java new file mode 100644 index 00000000000..8076a48d9a2 --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionWindowOpacityController.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.Context; +import android.content.res.Resources; + +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.accessibility.ListDialogPreference.OnValueChangedListener; +import com.android.settings.core.BasePreferenceController; + +/** Preference controller for caption window opacity. */ +public class CaptionWindowOpacityController extends BasePreferenceController + implements OnValueChangedListener { + + private final CaptionHelper mCaptionHelper; + + public CaptionWindowOpacityController(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); + final ColorPreference preference = screen.findPreference(getPreferenceKey()); + final Resources res = mContext.getResources(); + final int[] opacityValues = res.getIntArray(R.array.captioning_opacity_selector_values); + final String[] opacityTitles = res.getStringArray( + R.array.captioning_opacity_selector_titles); + preference.setTitles(opacityTitles); + preference.setValues(opacityValues); + final int windowColor = mCaptionHelper.getWindowColor(); + final int opacity = CaptionUtils.parseOpacity(windowColor); + preference.setValue(opacity); + preference.setOnValueChangedListener(this); + } + + @Override + public void onValueChanged(ListDialogPreference preference, int value) { + final int windowColor = mCaptionHelper.getWindowColor(); + final int color = CaptionUtils.parseColor(windowColor); + final int merged = CaptionUtils.mergeColorOpacity(color, value); + mCaptionHelper.setWindowColor(merged); + mCaptionHelper.setEnabled(true); + } +} diff --git a/tests/robotests/src/com/android/settings/accessibility/CaptionBackgroundColorControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionBackgroundColorControllerTest.java new file mode 100644 index 00000000000..964e240d658 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionBackgroundColorControllerTest.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.util.AttributeSet; +import android.view.accessibility.CaptioningManager; + +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; + +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.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowCaptioningManager; + +/** Tests for {@link CaptionBackgroundColorController}. */ +@RunWith(RobolectricTestRunner.class) +public class CaptionBackgroundColorControllerTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private PreferenceScreen mScreen; + private final Context mContext = ApplicationProvider.getApplicationContext(); + private CaptionBackgroundColorController mController; + private ColorPreference mPreference; + private ShadowCaptioningManager mShadowCaptioningManager; + + @Before + public void setUp() { + mController = new CaptionBackgroundColorController(mContext, "captioning_background_color"); + final AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + mPreference = new ColorPreference(mContext, attributeSet); + 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 getSummary_defaultValue_shouldReturnBlack() { + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Black"); + } + + @Test + public void getSummary_redValue_shouldReturnRed() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, 0xFFFF0000); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Red"); + } + + @Test + public void setRedValue_shouldReturnRed() { + mController.displayPreference(mScreen); + + mPreference.setValue(0xFFFF0000); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Red"); + } + + @Test + public void onValueChanged_shouldSetCaptionEnabled() { + mShadowCaptioningManager.setEnabled(false); + mController.displayPreference(mScreen); + + mController.onValueChanged(mPreference, 0xFFFF0000); + + 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/CaptionBackgroundOpacityControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionBackgroundOpacityControllerTest.java new file mode 100644 index 00000000000..3c5e247680c --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionBackgroundOpacityControllerTest.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.util.AttributeSet; +import android.view.accessibility.CaptioningManager; + +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; + +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.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowCaptioningManager; + +/** Tests for {@link CaptionBackgroundOpacityController}. */ +@RunWith(RobolectricTestRunner.class) +public class CaptionBackgroundOpacityControllerTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private PreferenceScreen mScreen; + private final Context mContext = ApplicationProvider.getApplicationContext(); + private CaptionBackgroundOpacityController mController; + private ColorPreference mPreference; + private ShadowCaptioningManager mShadowCaptioningManager; + + @Before + public void setUp() { + mController = + new CaptionBackgroundOpacityController(mContext, "captioning_background_opacity"); + final AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + mPreference = new ColorPreference(mContext, attributeSet); + 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 getSummary_defaultValue_shouldReturnNonTransparent() { + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("100%"); + } + + @Test + public void getSummary_halfTransparentValue_shouldReturnHalfTransparent() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, 0x80FFFFFF); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("50%"); + } + + @Test + public void setHalfTransparentValue_shouldReturnHalfTransparent() { + mController.displayPreference(mScreen); + + mPreference.setValue(0x80FFFFFF); + + assertThat(mPreference.getSummary().toString()).isEqualTo("50%"); + } + + @Test + public void onValueChanged_shouldSetCaptionEnabled() { + mShadowCaptioningManager.setEnabled(false); + mController.displayPreference(mScreen); + + mController.onValueChanged(mPreference, 0x80FFFFFF); + + 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/CaptionEdgeColorControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionEdgeColorControllerTest.java new file mode 100644 index 00000000000..fd4e55ad52d --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionEdgeColorControllerTest.java @@ -0,0 +1,113 @@ +/* + * 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.util.AttributeSet; +import android.view.accessibility.CaptioningManager; + +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; + +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.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowCaptioningManager; + +/** Tests for {@link CaptionEdgeColorController}. */ +@RunWith(RobolectricTestRunner.class) +public class CaptionEdgeColorControllerTest { + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private PreferenceScreen mScreen; + private final Context mContext = ApplicationProvider.getApplicationContext(); + private CaptionEdgeColorController mController; + private ColorPreference mPreference; + private ShadowCaptioningManager mShadowCaptioningManager; + + @Before + public void setUp() { + mController = new CaptionEdgeColorController(mContext, "captioning_edge_color"); + final AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + mPreference = new ColorPreference(mContext, attributeSet); + 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 getSummary_defaultValue_shouldReturnBlack() { + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Black"); + } + + @Test + public void getSummary_redValue_shouldReturnRed() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, 0xFFFF0000); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Red"); + } + + @Test + public void setRedValue_shouldReturnRed() { + mController.displayPreference(mScreen); + + mPreference.setValue(0xFFFF0000); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Red"); + } + + @Test + public void onValueChanged_shouldSetCaptionEnabled() { + mShadowCaptioningManager.setEnabled(false); + mController.displayPreference(mScreen); + + mController.onValueChanged(mPreference, 0xFFFF0000); + + 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/CaptionEdgeTypeControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionEdgeTypeControllerTest.java new file mode 100644 index 00000000000..fba7afaa873 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionEdgeTypeControllerTest.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.util.AttributeSet; +import android.view.accessibility.CaptioningManager; +import android.view.accessibility.CaptioningManager.CaptionStyle; + +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; + +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.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowCaptioningManager; + +/** Tests for {@link CaptionEdgeTypeController}. */ +@RunWith(RobolectricTestRunner.class) +public class CaptionEdgeTypeControllerTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private PreferenceScreen mScreen; + private final Context mContext = ApplicationProvider.getApplicationContext(); + private CaptionEdgeTypeController mController; + private EdgeTypePreference mPreference; + private ShadowCaptioningManager mShadowCaptioningManager; + + @Before + public void setUp() { + mController = new CaptionEdgeTypeController(mContext, "captioning_edge_type"); + final AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + mPreference = new EdgeTypePreference(mContext, attributeSet); + 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 getSummary_defaultValue_shouldReturnNone() { + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("None"); + } + + @Test + public void getSummary_outlineValue_shouldReturnOutline() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, CaptionStyle.EDGE_TYPE_OUTLINE); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Outline"); + } + + @Test + public void setOutlineValue_shouldReturnOutline() { + mController.displayPreference(mScreen); + + mPreference.setValue(CaptionStyle.EDGE_TYPE_OUTLINE); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Outline"); + } + + @Test + public void onValueChanged_shouldSetCaptionEnabled() { + mShadowCaptioningManager.setEnabled(false); + mController.displayPreference(mScreen); + + mController.onValueChanged(mPreference, CaptionStyle.EDGE_TYPE_OUTLINE); + + 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/CaptionForegroundColorControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionForegroundColorControllerTest.java new file mode 100644 index 00000000000..50ce90d5a9e --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionForegroundColorControllerTest.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.util.AttributeSet; +import android.view.accessibility.CaptioningManager; + +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; + +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.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowCaptioningManager; + +/** Tests for {@link CaptionForegroundColorController}. */ +@RunWith(RobolectricTestRunner.class) +public class CaptionForegroundColorControllerTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private PreferenceScreen mScreen; + private final Context mContext = ApplicationProvider.getApplicationContext(); + private CaptionForegroundColorController mController; + private ColorPreference mPreference; + private ShadowCaptioningManager mShadowCaptioningManager; + + @Before + public void setUp() { + mController = new CaptionForegroundColorController(mContext, "captioning_foreground_color"); + final AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + mPreference = new ColorPreference(mContext, attributeSet); + 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 getSummary_defaultValue_shouldReturnWhite() { + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("White"); + } + + @Test + public void getSummary_redValue_shouldReturnRed() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, 0xFFFF0000); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Red"); + } + + @Test + public void setRedValue_shouldReturnRed() { + mController.displayPreference(mScreen); + + mPreference.setValue(0xFFFF0000); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Red"); + } + + @Test + public void onValueChanged_shouldSetCaptionEnabled() { + mShadowCaptioningManager.setEnabled(false); + mController.displayPreference(mScreen); + + mController.onValueChanged(mPreference, 0xFFFF0000); + + 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/CaptionForegroundOpacityControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionForegroundOpacityControllerTest.java new file mode 100644 index 00000000000..38cecd65593 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionForegroundOpacityControllerTest.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.util.AttributeSet; +import android.view.accessibility.CaptioningManager; + +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; + +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.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowCaptioningManager; + +/** Tests for {@link CaptionForegroundOpacityController}. */ +@RunWith(RobolectricTestRunner.class) +public class CaptionForegroundOpacityControllerTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private PreferenceScreen mScreen; + private final Context mContext = ApplicationProvider.getApplicationContext(); + private CaptionForegroundOpacityController mController; + private ColorPreference mPreference; + private ShadowCaptioningManager mShadowCaptioningManager; + + @Before + public void setUp() { + mController = + new CaptionForegroundOpacityController(mContext, "captioning_foreground_opacity"); + final AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + mPreference = new ColorPreference(mContext, attributeSet); + 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 getSummary_defaultValue_shouldReturnNonTransparent() { + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("100%"); + } + + @Test + public void getSummary_halfTransparentValue_shouldReturnHalfTransparent() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, 0x80FFFFFF); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("50%"); + } + + @Test + public void setHalfTransparentValue_shouldReturnHalfTransparent() { + mController.displayPreference(mScreen); + + mPreference.setValue(0x80FFFFFF); + + assertThat(mPreference.getSummary().toString()).isEqualTo("50%"); + } + + @Test + public void onValueChanged_shouldSetCaptionEnabled() { + mShadowCaptioningManager.setEnabled(false); + mController.displayPreference(mScreen); + + mController.onValueChanged(mPreference, 0x80FFFFFF); + + 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 42d94540045..3047433db42 100644 --- a/tests/robotests/src/com/android/settings/accessibility/CaptionHelperTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionHelperTest.java @@ -28,6 +28,7 @@ import android.content.Context; import android.provider.Settings; import android.view.View; import android.view.accessibility.CaptioningManager; +import android.view.accessibility.CaptioningManager.CaptionStyle; import androidx.test.core.app.ApplicationProvider; @@ -129,4 +130,44 @@ public class CaptionHelperTest { Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON; assertThat(isCaptionEnabled).isFalse(); } + + @Test + public void setBackgroundColor_shouldReturnSpecificColor() { + mCaptionHelper.setBackgroundColor(0xFFFF0000); + + final int backgroundColor = mCaptionHelper.getBackgroundColor(); + assertThat(backgroundColor).isEqualTo(0xFFFF0000); + } + + @Test + public void setForegroundColor_shouldReturnSpecificColor() { + mCaptionHelper.setForegroundColor(0xFFFF0000); + + final int foregroundColor = mCaptionHelper.getForegroundColor(); + assertThat(foregroundColor).isEqualTo(0xFFFF0000); + } + + @Test + public void setWindowColor_shouldReturnSpecificColor() { + mCaptionHelper.setWindowColor(0xFFFF0000); + + final int windowColor = mCaptionHelper.getWindowColor(); + assertThat(windowColor).isEqualTo(0xFFFF0000); + } + + @Test + public void setEdgeColor_shouldReturnSpecificColor() { + mCaptionHelper.setEdgeColor(0xFFFF0000); + + final int edgeColor = mCaptionHelper.getEdgeColor(); + assertThat(edgeColor).isEqualTo(0xFFFF0000); + } + + @Test + public void setEdgeType_shouldReturnSpecificType() { + mCaptionHelper.setEdgeType(CaptionStyle.EDGE_TYPE_OUTLINE); + + final int edgeType = mCaptionHelper.getEdgeType(); + assertThat(edgeType).isEqualTo(CaptionStyle.EDGE_TYPE_OUTLINE); + } } diff --git a/tests/robotests/src/com/android/settings/accessibility/CaptionUtilsTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionUtilsTest.java new file mode 100644 index 00000000000..1e0f155b025 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionUtilsTest.java @@ -0,0 +1,80 @@ +/* + * 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.google.common.truth.Truth.assertThat; + +import android.graphics.Color; +import android.view.accessibility.CaptioningManager; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +/** Tests for {@link CaptionUtils}. */ +@RunWith(RobolectricTestRunner.class) +public class CaptionUtilsTest { + + @Test + public void parseColor_defaultPackedColor_shouldReturnUnspecified() { + final int color = CaptionUtils.parseColor(0xFFFF00); + + assertThat(color).isEqualTo(CaptioningManager.CaptionStyle.COLOR_UNSPECIFIED); + } + + @Test + public void parseColor_unrecognizedColor_shouldReturnTransparent() { + final int color = CaptionUtils.parseColor(0x00); + + assertThat(color).isEqualTo(Color.TRANSPARENT); + } + + @Test + public void parseColor_redColor_shouldReturnRed() { + final int color = CaptionUtils.parseColor(0xFFFF0000); + + assertThat(color).isEqualTo(Color.RED); + } + + @Test + public void parseOpacity_defaultPackedColor_shouldReturnUnspecified() { + final int color = CaptionUtils.parseOpacity(0xFFFF00); + + assertThat(color).isEqualTo(CaptioningManager.CaptionStyle.COLOR_UNSPECIFIED); + } + + @Test + public void parseOpacity_unrecognizedColor_shouldReturnTransparent() { + final int color = CaptionUtils.parseOpacity(0x00); + + assertThat(color).isEqualTo(0xFFFFFF); + } + + @Test + public void parseOpacity_halfTransparentValue_shouldReturnHalfTransparent() { + final int color = CaptionUtils.parseOpacity(0x80FFFFFF); + + assertThat(color).isEqualTo(0x80FFFFFF); + } + + @Test + public void mergeColorOpacity_halfTransparentRedValue_shouldReturnMergeColorOpacityValue() { + final int color = CaptionUtils.mergeColorOpacity(0xFFFF0000, 0x80FFFFFF); + + assertThat(color).isEqualTo(0x80FF0000); + } +} diff --git a/tests/robotests/src/com/android/settings/accessibility/CaptionWindowColorControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionWindowColorControllerTest.java new file mode 100644 index 00000000000..66b1666c46d --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionWindowColorControllerTest.java @@ -0,0 +1,116 @@ +/* + * 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.util.AttributeSet; +import android.view.accessibility.CaptioningManager; + +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.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowCaptioningManager; + +/** Tests for {@link CaptionWindowColorController}. */ +@RunWith(RobolectricTestRunner.class) +public class CaptionWindowColorControllerTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private PreferenceScreen mScreen; + private final Context mContext = ApplicationProvider.getApplicationContext(); + private CaptionWindowColorController mController; + private ColorPreference mPreference; + private ShadowCaptioningManager mShadowCaptioningManager; + + @Before + public void setUp() { + mController = new CaptionWindowColorController(mContext, "captioning_window_color"); + final AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + mPreference = new ColorPreference(mContext, attributeSet); + 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 getSummary_defaultValue_shouldReturnNone() { + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo( + mContext.getString(R.string.color_none)); + } + + @Test + public void getSummary_redValue_shouldReturnRed() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, 0xFFFF0000); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Red"); + } + + @Test + public void setRedValue_shouldReturnRed() { + mController.displayPreference(mScreen); + + mPreference.setValue(0xFFFF0000); + + assertThat(mPreference.getSummary().toString()).isEqualTo("Red"); + } + + @Test + public void onValueChanged_shouldSetCaptionEnabled() { + mShadowCaptioningManager.setEnabled(false); + mController.displayPreference(mScreen); + + mController.onValueChanged(mPreference, 0xFFFF0000); + + 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/CaptionWindowOpacityControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionWindowOpacityControllerTest.java new file mode 100644 index 00000000000..71d37482481 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/CaptionWindowOpacityControllerTest.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.util.AttributeSet; +import android.view.accessibility.CaptioningManager; + +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; + +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.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowCaptioningManager; + +/** Tests for {@link CaptionWindowOpacityController}. */ +@RunWith(RobolectricTestRunner.class) +public class CaptionWindowOpacityControllerTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private PreferenceScreen mScreen; + private final Context mContext = ApplicationProvider.getApplicationContext(); + private CaptionWindowOpacityController mController; + private ColorPreference mPreference; + private ShadowCaptioningManager mShadowCaptioningManager; + + @Before + public void setUp() { + mController = new CaptionWindowOpacityController(mContext, "captioning_window_opacity"); + final AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + mPreference = new ColorPreference(mContext, attributeSet); + 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 getSummary_defaultValue_shouldReturnNonTransparent() { + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("100%"); + } + + @Test + public void getSummary_halfTransparentValue_shouldReturnHalfTransparent() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, 0x80FFFFFF); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getSummary().toString()).isEqualTo("50%"); + } + + @Test + public void setHalfTransparentValue_shouldReturnHalfTransparent() { + mController.displayPreference(mScreen); + + mPreference.setValue(0x80FFFFFF); + + assertThat(mPreference.getSummary().toString()).isEqualTo("50%"); + } + + @Test + public void onValueChanged_shouldSetCaptionEnabled() { + mShadowCaptioningManager.setEnabled(false); + mController.displayPreference(mScreen); + + mController.onValueChanged(mPreference, 0x80FFFFFF); + + final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON; + assertThat(isCaptionEnabled).isTrue(); + } +}